From 2d278d9ab8145e512f8ce55aff7d69e4435f141a Mon Sep 17 00:00:00 2001 From: Alex Date: Fri, 2 Feb 2024 13:30:40 -0600 Subject: [PATCH 001/104] feat(web): search filter form (#6651) * refactor: search history box * filter box component * start adding forms * styling * combo box * styling * media types * album option * update * Updated * refactor: search history box * filter box component * start adding forms * styling * combo box * styling * media types * album option * update * Updated * Version v1.94.0 * Add people * add select even for combobox * Remove unused data * remove unused code * remove unused code --- .../components/elements/buttons/button.svelte | 3 + .../shared-components/change-date.svelte | 2 +- .../shared-components/combobox.svelte | 43 ++-- .../search-bar/search-bar.svelte | 90 +++----- .../search-bar/search-filter-box.svelte | 198 ++++++++++++++++++ .../search-bar/search-history-box.svelte | 62 ++++++ 6 files changed, 323 insertions(+), 75 deletions(-) create mode 100644 web/src/lib/components/shared-components/search-bar/search-filter-box.svelte create mode 100644 web/src/lib/components/shared-components/search-bar/search-history-box.svelte diff --git a/web/src/lib/components/elements/buttons/button.svelte b/web/src/lib/components/elements/buttons/button.svelte index b057d2da9a..6ef2f76bb4 100644 --- a/web/src/lib/components/elements/buttons/button.svelte +++ b/web/src/lib/components/elements/buttons/button.svelte @@ -4,6 +4,7 @@ | 'primary' | 'secondary' | 'transparent-primary' + | 'text-primary' | 'light-red' | 'red' | 'green' @@ -36,6 +37,8 @@ 'bg-gray-500 dark:bg-gray-200 text-white dark:text-immich-dark-gray enabled:hover:bg-gray-500/90 enabled:dark:hover:bg-gray-200/90', 'transparent-primary': 'text-gray-500 dark:text-immich-dark-primary enabled:hover:bg-gray-100 enabled:dark:hover:bg-gray-700', + 'text-primary': + 'text-immich-primary dark:text-immich-dark-primary enabled:dark:hover:bg-immich-dark-primary/10 enabled:hover:bg-immich-primary/10', 'light-red': 'bg-[#F9DEDC] text-[#410E0B] enabled:hover:bg-red-50', red: 'bg-red-500 text-white enabled:hover:bg-red-400', green: 'bg-green-500 text-gray-800 enabled:hover:bg-green-400/90', diff --git a/web/src/lib/components/shared-components/change-date.svelte b/web/src/lib/components/shared-components/change-date.svelte index 9edddc08c3..bf80fee5a1 100644 --- a/web/src/lib/components/shared-components/change-date.svelte +++ b/web/src/lib/components/shared-components/change-date.svelte @@ -85,7 +85,7 @@
- +
-
@@ -68,10 +78,11 @@
{#each filteredOptions as option (option.label)} -
-
- {/if} - - {#each $savedSearchTerms as savedSearchTerm, index (index)} -
-
- -
- -
-
-
- {/each} - + {#if showFilter} + {/if} diff --git a/web/src/lib/components/shared-components/search-bar/search-filter-box.svelte b/web/src/lib/components/shared-components/search-bar/search-filter-box.svelte new file mode 100644 index 0000000000..fe695979f2 --- /dev/null +++ b/web/src/lib/components/shared-components/search-bar/search-filter-box.svelte @@ -0,0 +1,198 @@ + + +
+

FILTERS

+
+ +
+
+ + +
+ +
+ +
+

MEDIA TYPE

+ +
+ + + + + +
+
+ + +
+

DISPLAY OPTIONS

+ +
+ + + + + +
+
+
+ +
+ + +
+
+
+

PEOPLE

+
+ +
+ +
+
+
+ +
+ +
+

PLACE

+ +
+
+

Country

+ +
+ +
+

State

+ +
+ +
+

City

+ +
+
+
+ +
+ +
+

CAMERA

+ +
+
+

Make

+ +
+ +
+

Model

+ +
+
+
+ +
+ + +
+
+ + +
+ +
+ + +
+
+ +
+ + +
+
+
diff --git a/web/src/lib/components/shared-components/search-bar/search-history-box.svelte b/web/src/lib/components/shared-components/search-bar/search-history-box.svelte new file mode 100644 index 0000000000..cb22513019 --- /dev/null +++ b/web/src/lib/components/shared-components/search-bar/search-history-box.svelte @@ -0,0 +1,62 @@ + + +
+
+

+ Smart search is enabled by default, to search for metadata use the syntax m:your-search-term +

+
+ + {#if $savedSearchTerms.length > 0} +
+

RECENT SEARCHES

+
+ +
+
+ {/if} + + {#each $savedSearchTerms as savedSearchTerm, i (i)} +
+
+ +
+ +
+
+
+ {/each} +
From b768eef44de548b0159ddf10f1dbab29c8efc837 Mon Sep 17 00:00:00 2001 From: Alex Date: Fri, 2 Feb 2024 14:58:13 -0600 Subject: [PATCH 002/104] fix(server): extract duration from video as ISO time (#6863) * fix(server): extract duration from video as ISO time * feedback and add test * fix test --- .../src/domain/metadata/metadata.service.spec.ts | 16 ++++++++++++++++ server/src/domain/metadata/metadata.service.ts | 7 +++++-- .../domain/repositories/metadata.repository.ts | 2 +- 3 files changed, 22 insertions(+), 3 deletions(-) diff --git a/server/src/domain/metadata/metadata.service.spec.ts b/server/src/domain/metadata/metadata.service.spec.ts index 9a3a4bfed1..e27e5f2ee3 100644 --- a/server/src/domain/metadata/metadata.service.spec.ts +++ b/server/src/domain/metadata/metadata.service.spec.ts @@ -547,6 +547,22 @@ describe(MetadataService.name, () => { ); }); + it('should handle duration in ISO time string', async () => { + assetMock.getByIds.mockResolvedValue([assetStub.image]); + metadataMock.readTags.mockResolvedValue({ Duration: '00:00:08.41' }); + + await sut.handleMetadataExtraction({ id: assetStub.image.id }); + + expect(assetMock.getByIds).toHaveBeenCalledWith([assetStub.image.id]); + expect(assetMock.upsertExif).toHaveBeenCalled(); + expect(assetMock.save).toHaveBeenCalledWith( + expect.objectContaining({ + id: assetStub.image.id, + duration: '00:00:08.410', + }), + ); + }); + it('should handle duration as an object without Scale', async () => { assetMock.getByIds.mockResolvedValue([assetStub.image]); metadataMock.readTags.mockResolvedValue({ Duration: { Value: 6.2 } }); diff --git a/server/src/domain/metadata/metadata.service.ts b/server/src/domain/metadata/metadata.service.ts index 12ad57006d..bcec1ac689 100644 --- a/server/src/domain/metadata/metadata.service.ts +++ b/server/src/domain/metadata/metadata.service.ts @@ -12,7 +12,6 @@ import { IBaseJob, IEntityJob, ISidecarWriteJob, JOBS_ASSET_PAGINATION_SIZE, Job import { ClientEvent, DatabaseLock, - ExifDuration, IAlbumRepository, IAssetRepository, ICommunicationRepository, @@ -555,11 +554,15 @@ export class MetadataService { return bitsPerSample; } - private getDuration(seconds?: number | ExifDuration): string { + private getDuration(seconds?: ImmichTags['Duration']): string { let _seconds = seconds as number; + if (typeof seconds === 'object') { _seconds = seconds.Value * (seconds?.Scale || 1); + } else if (typeof seconds === 'string') { + _seconds = Duration.fromISOTime(seconds).as('seconds'); } + return Duration.fromObject({ seconds: _seconds }).toFormat('hh:mm:ss.SSS'); } } diff --git a/server/src/domain/repositories/metadata.repository.ts b/server/src/domain/repositories/metadata.repository.ts index 98df4517ae..ca9cfe4977 100644 --- a/server/src/domain/repositories/metadata.repository.ts +++ b/server/src/domain/repositories/metadata.repository.ts @@ -26,7 +26,7 @@ export interface ImmichTags extends Omit { MediaGroupUUID?: string; ImagePixelDepth?: string; FocalLength?: number; - Duration?: number | ExifDuration; + Duration?: number | string | ExifDuration; EmbeddedVideoType?: string; EmbeddedVideoFile?: BinaryField; MotionPhotoVideo?: BinaryField; From 79d3342c3dad33dd40a35c71c09d8b65c9f61ff5 Mon Sep 17 00:00:00 2001 From: Mert <101130780+mertalev@users.noreply.github.com> Date: Sat, 3 Feb 2024 00:35:26 -0500 Subject: [PATCH 003/104] fix(ml): openvino not working with dynamic axes (#6871) * convert to static * add comment about gross code * formatting * fixed test * fix typing * cleanup * formatting * Revert "formatting" This reverts commit 073965c47e7e31f1255fd461cd34ee19917d78bb. * Revert "cleanup" This reverts commit bb56bd3297303332b25bdc3b112cfc278ee593ba. * formatting --- machine-learning/app/models/base.py | 48 +++++++++++++++++++++++- machine-learning/app/models/constants.py | 9 ++--- 2 files changed, 51 insertions(+), 6 deletions(-) diff --git a/machine-learning/app/models/base.py b/machine-learning/app/models/base.py index e5ebb828f3..1c15a9d41a 100644 --- a/machine-learning/app/models/base.py +++ b/machine-learning/app/models/base.py @@ -6,12 +6,15 @@ from pathlib import Path from shutil import rmtree from typing import Any +import onnx import onnxruntime as ort from huggingface_hub import snapshot_download +from onnx.shape_inference import infer_shapes +from onnx.tools.update_model_dims import update_inputs_outputs_dims from typing_extensions import Buffer import ann.ann -from app.models.constants import SUPPORTED_PROVIDERS +from app.models.constants import STATIC_INPUT_PROVIDERS, SUPPORTED_PROVIDERS from ..config import get_cache_dir, get_hf_model_name, log, settings from ..schemas import ModelRuntime, ModelType @@ -114,6 +117,13 @@ class InferenceModel(ABC): ) model_path = onnx_path + if any(provider in STATIC_INPUT_PROVIDERS for provider in self.providers): + static_path = model_path.parent / "static_1" / "model.onnx" + static_path.parent.mkdir(parents=True, exist_ok=True) + if not static_path.is_file(): + self._convert_to_static(model_path, static_path) + model_path = static_path + match model_path.suffix: case ".armnn": session = AnnSession(model_path) @@ -128,6 +138,42 @@ class InferenceModel(ABC): raise ValueError(f"Unsupported model file type: {model_path.suffix}") return session + def _convert_to_static(self, source_path: Path, target_path: Path) -> None: + inferred = infer_shapes(onnx.load(source_path)) + inputs = self._get_static_dims(inferred.graph.input) + outputs = self._get_static_dims(inferred.graph.output) + + # check_model gets called in update_inputs_outputs_dims and doesn't work for large models + check_model = onnx.checker.check_model + try: + + def check_model_stub(*args: Any, **kwargs: Any) -> None: + pass + + onnx.checker.check_model = check_model_stub + updated_model = update_inputs_outputs_dims(inferred, inputs, outputs) + finally: + onnx.checker.check_model = check_model + + onnx.save( + updated_model, + target_path, + save_as_external_data=True, + all_tensors_to_one_file=False, + size_threshold=1048576, + ) + + def _get_static_dims(self, graph_io: Any, dim_size: int = 1) -> dict[str, list[int]]: + return { + field.name: [ + d.dim_value if d.HasField("dim_value") else dim_size + for shape in field.type.ListFields() + if (dim := shape[1].shape.dim) + for d in dim + ] + for field in graph_io + } + @property def model_type(self) -> ModelType: return self._model_type diff --git a/machine-learning/app/models/constants.py b/machine-learning/app/models/constants.py index edfe68aa70..18965d2b1d 100644 --- a/machine-learning/app/models/constants.py +++ b/machine-learning/app/models/constants.py @@ -51,11 +51,10 @@ _INSIGHTFACE_MODELS = { } -SUPPORTED_PROVIDERS = [ - "CUDAExecutionProvider", - "OpenVINOExecutionProvider", - "CPUExecutionProvider", -] +SUPPORTED_PROVIDERS = ["CUDAExecutionProvider", "OpenVINOExecutionProvider", "CPUExecutionProvider"] + + +STATIC_INPUT_PROVIDERS = ["OpenVINOExecutionProvider"] def is_openclip(model_name: str) -> bool: From a4cfb51df5a4f34f9644ee12fc7f8c64c12c7088 Mon Sep 17 00:00:00 2001 From: Ben McCann <322311+benmccann@users.noreply.github.com> Date: Fri, 2 Feb 2024 21:44:53 -0800 Subject: [PATCH 004/104] chore: remove `form-data` dependency (#6876) chore: remove form-data dependency --- .github/workflows/test.yml | 10 ++++++++++ cli/package-lock.json | 13 ++++++------- cli/package.json | 4 +++- cli/src/commands/upload.command.ts | 10 ++++------ 4 files changed, 23 insertions(+), 14 deletions(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index bff3f484a9..58761eea05 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -103,6 +103,11 @@ jobs: - name: Checkout code uses: actions/checkout@v4 + - name: Setup Node + uses: actions/setup-node@v4 + with: + node-version: 20 + - name: Run setup typescript-sdk run: npm ci && npm run build working-directory: ./open-api/typescript-sdk @@ -143,6 +148,11 @@ jobs: with: submodules: "recursive" + - name: Setup Node + uses: actions/setup-node@v4 + with: + node-version: 20 + - name: Run setup typescript-sdk run: npm ci && npm run build working-directory: ./open-api/typescript-sdk diff --git a/cli/package-lock.json b/cli/package-lock.json index 9c218f78b9..3d8ba6005f 100644 --- a/cli/package-lock.json +++ b/cli/package-lock.json @@ -14,7 +14,6 @@ "byte-size": "^8.1.1", "cli-progress": "^3.12.0", "commander": "^11.0.0", - "form-data": "^4.0.0", "glob": "^10.3.1", "yaml": "^2.3.1" }, @@ -27,8 +26,8 @@ "@types/cli-progress": "^3.11.0", "@types/mock-fs": "^4.13.1", "@types/node": "^20.3.1", - "@typescript-eslint/eslint-plugin": "^6.0.0", - "@typescript-eslint/parser": "^6.0.0", + "@typescript-eslint/eslint-plugin": "^6.4.1", + "@typescript-eslint/parser": "^6.4.1", "@vitest/coverage-v8": "^1.2.2", "eslint": "^8.56.0", "eslint-config-prettier": "^9.1.0", @@ -56,7 +55,7 @@ }, "../server": { "name": "immich", - "version": "1.93.3", + "version": "1.94.1", "dev": true, "license": "UNLICENSED", "dependencies": { @@ -79,6 +78,7 @@ "axios": "^1.5.0", "bcrypt": "^5.1.1", "bullmq": "^4.8.0", + "chokidar": "^3.5.3", "class-transformer": "^0.5.1", "class-validator": "^0.14.0", "cookie-parser": "^1.4.6", @@ -129,7 +129,6 @@ "@types/ua-parser-js": "^0.7.36", "@typescript-eslint/eslint-plugin": "^6.4.1", "@typescript-eslint/parser": "^6.4.1", - "chokidar": "^3.5.3", "dotenv": "^16.3.1", "eslint": "^8.56.0", "eslint-config-prettier": "^9.1.0", @@ -149,7 +148,7 @@ "ts-loader": "^9.4.4", "ts-node": "^10.9.1", "tsconfig-paths": "^4.2.0", - "typescript": "^5.2.2", + "typescript": "^5.3.3", "utimes": "^5.2.1" } }, @@ -8828,7 +8827,7 @@ "ts-node": "^10.9.1", "tsconfig-paths": "^4.2.0", "typeorm": "^0.3.17", - "typescript": "^5.2.2", + "typescript": "^5.3.3", "ua-parser-js": "^1.0.35", "utimes": "^5.2.1" } diff --git a/cli/package.json b/cli/package.json index 9e32061e3d..64691b5cdd 100644 --- a/cli/package.json +++ b/cli/package.json @@ -18,7 +18,6 @@ "byte-size": "^8.1.1", "cli-progress": "^3.12.0", "commander": "^11.0.0", - "form-data": "^4.0.0", "glob": "^10.3.1", "yaml": "^2.3.1" }, @@ -58,5 +57,8 @@ "type": "git", "url": "github:immich-app/immich", "directory": "cli" + }, + "engines": { + "node": ">=20.0.0" } } diff --git a/cli/src/commands/upload.command.ts b/cli/src/commands/upload.command.ts index f026e374df..b5ea6aa0fd 100644 --- a/cli/src/commands/upload.command.ts +++ b/cli/src/commands/upload.command.ts @@ -1,8 +1,7 @@ import axios, { AxiosRequestConfig, AxiosResponse } from 'axios'; import byteSize from 'byte-size'; import cliProgress from 'cli-progress'; -import FormData from 'form-data'; -import fs, { ReadStream, createReadStream } from 'node:fs'; +import fs, { createReadStream } from 'node:fs'; import { CrawlService } from '../services/crawl.service'; import { BaseCommand } from './base-command'; import { basename } from 'node:path'; @@ -47,14 +46,14 @@ class Asset { // TODO: doesn't xmp replace the file extension? Will need investigation const sideCarPath = `${this.path}.xmp`; - let sidecarData: ReadStream | undefined = undefined; + let sidecarData: Blob | undefined = undefined; try { await access(sideCarPath, constants.R_OK); - sidecarData = createReadStream(sideCarPath); + sidecarData = new File([await fs.openAsBlob(sideCarPath)], basename(sideCarPath)); } catch {} const data: any = { - assetData: createReadStream(this.path), + assetData: new File([await fs.openAsBlob(this.path)], basename(this.path)), deviceAssetId: this.deviceAssetId, deviceId: 'CLI', fileCreatedAt: this.fileCreatedAt, @@ -269,7 +268,6 @@ export class UploadCommand extends BaseCommand { url, headers: { 'x-api-key': this.immichApi.apiKey, - ...data.getHeaders(), }, maxContentLength: Number.POSITIVE_INFINITY, maxBodyLength: Number.POSITIVE_INFINITY, From 329659b2fba54cebab7bd7fee404b28f28be5de5 Mon Sep 17 00:00:00 2001 From: Mert <101130780+mertalev@users.noreply.github.com> Date: Sat, 3 Feb 2024 09:11:53 -0500 Subject: [PATCH 005/104] docs(ml,server): updated hwaccel docs (#6878) --- docs/docs/features/hardware-transcoding.md | 52 +++++++++++----- .../docs/features/ml-hardware-acceleration.md | 59 ++++++++++++++++++- 2 files changed, 95 insertions(+), 16 deletions(-) diff --git a/docs/docs/features/hardware-transcoding.md b/docs/docs/features/hardware-transcoding.md index 0bc5a2f19c..db3d1ba7d6 100644 --- a/docs/docs/features/hardware-transcoding.md +++ b/docs/docs/features/hardware-transcoding.md @@ -4,6 +4,10 @@ This feature allows you to use a GPU to accelerate transcoding and reduce CPU lo Note that hardware transcoding is much less efficient for file sizes. As this is a new feature, it is still experimental and may not work on all systems. +:::info +You do not need to redo any transcoding jobs after enabling hardware acceleration. The acceleration device will be used for any jobs that run after enabling it. +::: + ## Supported APIs - NVENC (NVIDIA) @@ -50,6 +54,40 @@ As this is a new feature, it is still experimental and may not work on all syste 3. Redeploy the `immich-microservices` container with these updated settings. 4. In the Admin page under `Video transcoding settings`, change the hardware acceleration setting to the appropriate option and save. +#### Single Compose File + +Some platforms, including Unraid and Portainer, do not support multiple Compose files as of writing. As an alternative, you can "inline" the relevant contents of the [`hwaccel.transcoding.yml`][hw-file] file into the `immich-microservices` service directly. + +For example, the `qsv` section in this file is: + +```yaml +devices: + - /dev/dri:/dev/dri +``` + +You can add this to the `immich-microservices` service instead of extending from `hwaccel.transcoding.yml`: + +```yaml +immich-microservices: + container_name: immich_microservices + image: ghcr.io/immich-app/immich-server:${IMMICH_VERSION:-release} + # Note the lack of an `extends` section + devices: + - /dev/dri:/dev/dri + command: ['start.sh', 'microservices'] + volumes: + - ${UPLOAD_LOCATION}:/usr/src/app/upload + - /etc/localtime:/etc/localtime:ro + env_file: + - .env + depends_on: + - redis + - database + restart: always +``` + +Once this is done, you can continue to step 3 of "Basic Setup". + #### All-In-One - Unraid Setup ##### NVENC - NVIDIA GPUs @@ -59,20 +97,6 @@ As this is a new feature, it is still experimental and may not work on all syste 3. Restart the container app. 4. Continue to step 4 of "Basic Setup". -##### Other APIs - -Unraid does not currently support multiple Compose files. As an alternative, you can "inline" the relevant contents of the [`hwaccel.transcoding.yml`][hw-file] file into the `immich-microservices` service directly. - -For example, the `qsv` section in this file is: - -``` -devices: - - /dev/dri:/dev/dri -``` - -You can add this to the `immich-microservices` service instead of extending from `hwaccel.transcoding.yml`. -Once this is done, you can continue to step 3 of "Basic Setup". - ## Tips - You may want to choose a slower preset than for software transcoding to maintain quality and efficiency diff --git a/docs/docs/features/ml-hardware-acceleration.md b/docs/docs/features/ml-hardware-acceleration.md index 2323b468cb..b50185c580 100644 --- a/docs/docs/features/ml-hardware-acceleration.md +++ b/docs/docs/features/ml-hardware-acceleration.md @@ -3,7 +3,11 @@ This feature allows you to use a GPU to accelerate machine learning tasks, such as Smart Search and Facial Recognition, while reducing CPU load. As this is a new feature, it is still experimental and may not work on all systems. -## Supported APIs +:::info +You do not need to redo any machine learning jobs after enabling hardware acceleration. The acceleration device will be used for any jobs that run after enabling it. +::: + +## Supported Backends - ARM NN (Mali) - CUDA (NVIDIA) @@ -14,7 +18,8 @@ As this is a new feature, it is still experimental and may not work on all syste - The instructions and configurations here are specific to Docker Compose. Other container engines may require different configuration. - Only Linux and Windows (through WSL2) servers are supported. - ARM NN is only supported on devices with Mali GPUs. Other Arm devices are not supported. -- The OpenVINO backend has only been tested on an iGPU. ARC GPUs may not work without other changes. +- There is currently an upstream issue with OpenVINO, so whether it will work is device-dependent. +- Some models may not be compatible with certain backends. CUDA is the most reliable. ## Prerequisites @@ -40,10 +45,60 @@ As this is a new feature, it is still experimental and may not work on all syste 2. In the `docker-compose.yml` under `immich-machine-learning`, uncomment the `extends` section and change `cpu` to the appropriate backend. 3. Redeploy the `immich-machine-learning` container with these updated settings. +#### Single Compose File + +Some platforms, including Unraid and Portainer, do not support multiple Compose files as of writing. As an alternative, you can "inline" the relevant contents of the [`hwaccel.ml.yml`][hw-file] file into the `immich-machine-learning` service directly. + +For example, the `cuda` section in this file is: + +```yaml +deploy: + resources: + reservations: + devices: + - driver: nvidia + count: 1 + capabilities: + - gpu + - compute + - video +``` + +You can add this to the `immich-machine-learning` service instead of extending from `hwaccel.ml.yml`: + +```yaml +immich-machine-learning: + container_name: immich_machine_learning + image: ghcr.io/immich-app/immich-machine-learning:${IMMICH_VERSION:-release} + # Note the lack of an `extends` section + deploy: + resources: + reservations: + devices: + - driver: nvidia + count: 1 + capabilities: + - gpu + - compute + - video + volumes: + - model-cache:/cache + env_file: + - .env + restart: always +``` + +Once this is done, you can redeploy the `immich-machine-learning` container. + +:::info +You can confirm the device is being recognized and used by checking its utilization (via `nvtop` for CUDA, `intel_gpu_top` for OpenVINO, etc.). You can also enable debug logging by setting `LOG_LEVEL=debug` in the `.env` file and restarting the `immich-machine-learning` container. When a Smart Search or Face Detection job begins, you should see a log for `Available ORT providers` containing the relevant provider. In the case of ARM NN, the absence of a `Could not load ANN shared libraries` log entry means it loaded successfully. +::: + [hw-file]: https://github.com/immich-app/immich/releases/latest/download/hwaccel.ml.yml [nvcr]: https://github.com/NVIDIA/nvidia-container-runtime/ ## Tips +- If you encounter an error when a model is running, try a different model to see if the issue is model-specific. - You may want to increase concurrency past the default for higher utilization. However, keep in mind that this will also increase VRAM consumption. - Larger models benefit more from hardware acceleration, if you have the VRAM for them. From b4c211cad10b427ca468abdcb539d1b85ae08ee2 Mon Sep 17 00:00:00 2001 From: Ben McCann <322311+benmccann@users.noreply.github.com> Date: Sat, 3 Feb 2024 19:39:01 -0800 Subject: [PATCH 006/104] fix: bundle CLI with Vite (#6893) * fix: bundle CLI with Vite * bundle dependencies as well * remove unused dependencies --- cli/package-lock.json | 772 ++++++++-------------------------------- cli/package.json | 23 +- cli/tsconfig.build.json | 4 - cli/vite.config.ts | 17 + 4 files changed, 178 insertions(+), 638 deletions(-) delete mode 100644 cli/tsconfig.build.json create mode 100644 cli/vite.config.ts diff --git a/cli/package-lock.json b/cli/package-lock.json index 3d8ba6005f..7acfa36670 100644 --- a/cli/package-lock.json +++ b/cli/package-lock.json @@ -8,19 +8,11 @@ "name": "@immich/cli", "version": "2.0.6", "license": "MIT", - "dependencies": { - "@immich/sdk": "file:../open-api/typescript-sdk", - "axios": "^1.6.7", - "byte-size": "^8.1.1", - "cli-progress": "^3.12.0", - "commander": "^11.0.0", - "glob": "^10.3.1", - "yaml": "^2.3.1" - }, "bin": { "immich": "dist/src/index.js" }, "devDependencies": { + "@immich/sdk": "file:../open-api/typescript-sdk", "@testcontainers/postgresql": "^10.4.0", "@types/byte-size": "^8.1.0", "@types/cli-progress": "^3.11.0", @@ -29,21 +21,30 @@ "@typescript-eslint/eslint-plugin": "^6.4.1", "@typescript-eslint/parser": "^6.4.1", "@vitest/coverage-v8": "^1.2.2", + "axios": "^1.6.7", + "byte-size": "^8.1.1", + "cli-progress": "^3.12.0", + "commander": "^11.0.0", "eslint": "^8.56.0", "eslint-config-prettier": "^9.1.0", "eslint-plugin-prettier": "^5.1.3", "eslint-plugin-unicorn": "^50.0.1", + "glob": "^10.3.1", "immich": "file:../server", "mock-fs": "^5.2.0", - "ts-node": "^10.9.1", - "tslib": "^2.5.3", "typescript": "^5.3.3", - "vitest": "^1.2.1" + "vite": "^5.0.12", + "vitest": "^1.2.1", + "yaml": "^2.3.1" + }, + "engines": { + "node": ">=20.0.0" } }, "../open-api/typescript-sdk": { "name": "@immich/sdk", "version": "1.92.1", + "dev": true, "license": "MIT", "dependencies": { "axios": "^1.6.7" @@ -399,28 +400,6 @@ "integrity": "sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==", "dev": true }, - "node_modules/@cspotcode/source-map-support": { - "version": "0.8.1", - "resolved": "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz", - "integrity": "sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==", - "dev": true, - "dependencies": { - "@jridgewell/trace-mapping": "0.3.9" - }, - "engines": { - "node": ">=12" - } - }, - "node_modules/@cspotcode/source-map-support/node_modules/@jridgewell/trace-mapping": { - "version": "0.3.9", - "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.9.tgz", - "integrity": "sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==", - "dev": true, - "dependencies": { - "@jridgewell/resolve-uri": "^3.0.3", - "@jridgewell/sourcemap-codec": "^1.4.10" - } - }, "node_modules/@esbuild/aix-ppc64": { "version": "0.19.12", "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.19.12.tgz", @@ -886,6 +865,7 @@ "version": "8.0.2", "resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-8.0.2.tgz", "integrity": "sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==", + "dev": true, "dependencies": { "string-width": "^5.1.2", "string-width-cjs": "npm:string-width@^4.2.0", @@ -902,6 +882,7 @@ "version": "6.0.1", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.0.1.tgz", "integrity": "sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==", + "dev": true, "engines": { "node": ">=12" }, @@ -912,12 +893,14 @@ "node_modules/@isaacs/cliui/node_modules/emoji-regex": { "version": "9.2.2", "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz", - "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==" + "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==", + "dev": true }, "node_modules/@isaacs/cliui/node_modules/string-width": { "version": "5.1.2", "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz", "integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==", + "dev": true, "dependencies": { "eastasianwidth": "^0.2.0", "emoji-regex": "^9.2.2", @@ -934,6 +917,7 @@ "version": "7.1.0", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", + "dev": true, "dependencies": { "ansi-regex": "^6.0.1" }, @@ -1052,6 +1036,7 @@ "version": "0.11.0", "resolved": "https://registry.npmjs.org/@pkgjs/parseargs/-/parseargs-0.11.0.tgz", "integrity": "sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==", + "dev": true, "optional": true, "engines": { "node": ">=14" @@ -1244,232 +1229,6 @@ "integrity": "sha512-+Fj43pSMwJs4KRrH/938Uf+uAELIgVBmQzg/q1YG10djyfA3TnrU8N8XzqCh/okZdszqBQTZf96idMfE5lnwTA==", "dev": true }, - "node_modules/@swc/core": { - "version": "1.3.107", - "resolved": "https://registry.npmjs.org/@swc/core/-/core-1.3.107.tgz", - "integrity": "sha512-zKhqDyFcTsyLIYK1iEmavljZnf4CCor5pF52UzLAz4B6Nu/4GLU+2LQVAf+oRHjusG39PTPjd2AlRT3f3QWfsQ==", - "dev": true, - "hasInstallScript": true, - "optional": true, - "peer": true, - "dependencies": { - "@swc/counter": "^0.1.1", - "@swc/types": "^0.1.5" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/swc" - }, - "optionalDependencies": { - "@swc/core-darwin-arm64": "1.3.107", - "@swc/core-darwin-x64": "1.3.107", - "@swc/core-linux-arm-gnueabihf": "1.3.107", - "@swc/core-linux-arm64-gnu": "1.3.107", - "@swc/core-linux-arm64-musl": "1.3.107", - "@swc/core-linux-x64-gnu": "1.3.107", - "@swc/core-linux-x64-musl": "1.3.107", - "@swc/core-win32-arm64-msvc": "1.3.107", - "@swc/core-win32-ia32-msvc": "1.3.107", - "@swc/core-win32-x64-msvc": "1.3.107" - }, - "peerDependencies": { - "@swc/helpers": "^0.5.0" - }, - "peerDependenciesMeta": { - "@swc/helpers": { - "optional": true - } - } - }, - "node_modules/@swc/core-darwin-arm64": { - "version": "1.3.107", - "resolved": "https://registry.npmjs.org/@swc/core-darwin-arm64/-/core-darwin-arm64-1.3.107.tgz", - "integrity": "sha512-47tD/5vSXWxPd0j/ZllyQUg4bqalbQTsmqSw0J4dDdS82MWqCAwUErUrAZPRjBkjNQ6Kmrf5rpCWaGTtPw+ngw==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "darwin" - ], - "peer": true, - "engines": { - "node": ">=10" - } - }, - "node_modules/@swc/core-darwin-x64": { - "version": "1.3.107", - "resolved": "https://registry.npmjs.org/@swc/core-darwin-x64/-/core-darwin-x64-1.3.107.tgz", - "integrity": "sha512-hwiLJ2ulNkBGAh1m1eTfeY1417OAYbRGcb/iGsJ+LuVLvKAhU/itzsl535CvcwAlt2LayeCFfcI8gdeOLeZa9A==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "darwin" - ], - "peer": true, - "engines": { - "node": ">=10" - } - }, - "node_modules/@swc/core-linux-arm-gnueabihf": { - "version": "1.3.107", - "resolved": "https://registry.npmjs.org/@swc/core-linux-arm-gnueabihf/-/core-linux-arm-gnueabihf-1.3.107.tgz", - "integrity": "sha512-I2wzcC0KXqh0OwymCmYwNRgZ9nxX7DWnOOStJXV3pS0uB83TXAkmqd7wvMBuIl9qu4Hfomi9aDM7IlEEn9tumQ==", - "cpu": [ - "arm" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "peer": true, - "engines": { - "node": ">=10" - } - }, - "node_modules/@swc/core-linux-arm64-gnu": { - "version": "1.3.107", - "resolved": "https://registry.npmjs.org/@swc/core-linux-arm64-gnu/-/core-linux-arm64-gnu-1.3.107.tgz", - "integrity": "sha512-HWgnn7JORYlOYnGsdunpSF8A+BCZKPLzLtEUA27/M/ZuANcMZabKL9Zurt7XQXq888uJFAt98Gy+59PU90aHKg==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "peer": true, - "engines": { - "node": ">=10" - } - }, - "node_modules/@swc/core-linux-arm64-musl": { - "version": "1.3.107", - "resolved": "https://registry.npmjs.org/@swc/core-linux-arm64-musl/-/core-linux-arm64-musl-1.3.107.tgz", - "integrity": "sha512-vfPF74cWfAm8hyhS8yvYI94ucMHIo8xIYU+oFOW9uvDlGQRgnUf/6DEVbLyt/3yfX5723Ln57U8uiMALbX5Pyw==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "peer": true, - "engines": { - "node": ">=10" - } - }, - "node_modules/@swc/core-linux-x64-gnu": { - "version": "1.3.107", - "resolved": "https://registry.npmjs.org/@swc/core-linux-x64-gnu/-/core-linux-x64-gnu-1.3.107.tgz", - "integrity": "sha512-uBVNhIg0ip8rH9OnOsCARUFZ3Mq3tbPHxtmWk9uAa5u8jQwGWeBx5+nTHpDOVd3YxKb6+5xDEI/edeeLpha/9g==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "peer": true, - "engines": { - "node": ">=10" - } - }, - "node_modules/@swc/core-linux-x64-musl": { - "version": "1.3.107", - "resolved": "https://registry.npmjs.org/@swc/core-linux-x64-musl/-/core-linux-x64-musl-1.3.107.tgz", - "integrity": "sha512-mvACkUvzSIB12q1H5JtabWATbk3AG+pQgXEN95AmEX2ZA5gbP9+B+mijsg7Sd/3tboHr7ZHLz/q3SHTvdFJrEw==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "peer": true, - "engines": { - "node": ">=10" - } - }, - "node_modules/@swc/core-win32-arm64-msvc": { - "version": "1.3.107", - "resolved": "https://registry.npmjs.org/@swc/core-win32-arm64-msvc/-/core-win32-arm64-msvc-1.3.107.tgz", - "integrity": "sha512-J3P14Ngy/1qtapzbguEH41kY109t6DFxfbK4Ntz9dOWNuVY3o9/RTB841ctnJk0ZHEG+BjfCJjsD2n8H5HcaOA==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "win32" - ], - "peer": true, - "engines": { - "node": ">=10" - } - }, - "node_modules/@swc/core-win32-ia32-msvc": { - "version": "1.3.107", - "resolved": "https://registry.npmjs.org/@swc/core-win32-ia32-msvc/-/core-win32-ia32-msvc-1.3.107.tgz", - "integrity": "sha512-ZBUtgyjTHlz8TPJh7kfwwwFma+ktr6OccB1oXC8fMSopD0AxVnQasgun3l3099wIsAB9eEsJDQ/3lDkOLs1gBA==", - "cpu": [ - "ia32" - ], - "dev": true, - "optional": true, - "os": [ - "win32" - ], - "peer": true, - "engines": { - "node": ">=10" - } - }, - "node_modules/@swc/core-win32-x64-msvc": { - "version": "1.3.107", - "resolved": "https://registry.npmjs.org/@swc/core-win32-x64-msvc/-/core-win32-x64-msvc-1.3.107.tgz", - "integrity": "sha512-Eyzo2XRqWOxqhE1gk9h7LWmUf4Bp4Xn2Ttb0ayAXFp6YSTxQIThXcT9kipXZqcpxcmDwoq8iWbbf2P8XL743EA==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "win32" - ], - "peer": true, - "engines": { - "node": ">=10" - } - }, - "node_modules/@swc/counter": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/@swc/counter/-/counter-0.1.2.tgz", - "integrity": "sha512-9F4ys4C74eSTEUNndnER3VJ15oru2NumfQxS8geE+f3eB5xvfxpWyqE5XlVnxb/R14uoXi6SLbBwwiDSkv+XEw==", - "dev": true, - "optional": true, - "peer": true - }, - "node_modules/@swc/types": { - "version": "0.1.5", - "resolved": "https://registry.npmjs.org/@swc/types/-/types-0.1.5.tgz", - "integrity": "sha512-myfUej5naTBWnqOCc/MdVOLVjXUXtIA+NpDrDBKJtLLg2shUjBu3cZmB/85RyitKc55+lUUyl7oRfLOvkr2hsw==", - "dev": true, - "optional": true, - "peer": true - }, "node_modules/@testcontainers/postgresql": { "version": "10.6.0", "resolved": "https://registry.npmjs.org/@testcontainers/postgresql/-/postgresql-10.6.0.tgz", @@ -1479,30 +1238,6 @@ "testcontainers": "^10.6.0" } }, - "node_modules/@tsconfig/node10": { - "version": "1.0.9", - "resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.9.tgz", - "integrity": "sha512-jNsYVVxU8v5g43Erja32laIDHXeoNvFEpX33OK4d6hljo3jDhCBDhx5dhCCTMWUojscpAagGiRkBKxpdl9fxqA==", - "dev": true - }, - "node_modules/@tsconfig/node12": { - "version": "1.0.11", - "resolved": "https://registry.npmjs.org/@tsconfig/node12/-/node12-1.0.11.tgz", - "integrity": "sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag==", - "dev": true - }, - "node_modules/@tsconfig/node14": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/@tsconfig/node14/-/node14-1.0.3.tgz", - "integrity": "sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow==", - "dev": true - }, - "node_modules/@tsconfig/node16": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/@tsconfig/node16/-/node16-1.0.4.tgz", - "integrity": "sha512-vxhUy4J8lyeyinH7Azl1pdd43GJhZH/tP2weN8TntQblOY+A0XbT8DJk1/oCPuOOyg/Ja757rG0CgHcWC8OfMA==", - "dev": true - }, "node_modules/@types/byte-size": { "version": "8.1.2", "resolved": "https://registry.npmjs.org/@types/byte-size/-/byte-size-8.1.2.tgz", @@ -2238,6 +1973,7 @@ "version": "5.0.1", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true, "engines": { "node": ">=8" } @@ -2246,6 +1982,7 @@ "version": "4.3.0", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, "dependencies": { "color-convert": "^2.0.1" }, @@ -2345,12 +2082,6 @@ "safe-buffer": "~5.1.0" } }, - "node_modules/arg": { - "version": "4.1.3", - "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz", - "integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==", - "dev": true - }, "node_modules/argparse": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", @@ -2399,12 +2130,14 @@ "node_modules/asynckit": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", - "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==" + "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==", + "dev": true }, "node_modules/axios": { "version": "1.6.7", "resolved": "https://registry.npmjs.org/axios/-/axios-1.6.7.tgz", "integrity": "sha512-/hDJGff6/c7u0hDkvkGxR/oy6CbCs8ziCsC7SqmhjfozqiJGc8Z11wrv9z9lYfY4K8l+H9TpjcMDX0xOZmx+RA==", + "dev": true, "dependencies": { "follow-redirects": "^1.15.4", "form-data": "^4.0.0", @@ -2420,7 +2153,8 @@ "node_modules/balanced-match": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", - "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==" + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", + "dev": true }, "node_modules/base64-js": { "version": "1.5.1", @@ -2584,6 +2318,7 @@ "version": "8.1.1", "resolved": "https://registry.npmjs.org/byte-size/-/byte-size-8.1.1.tgz", "integrity": "sha512-tUkzZWK0M/qdoLEqikxBWe4kumyuwjl3HO6zHTr4yEI23EojPtLYXdG1+AQY7MN0cGyNDvEaJ8wiYQm6P2bPxg==", + "dev": true, "engines": { "node": ">=12.17" } @@ -2703,6 +2438,7 @@ "version": "3.12.0", "resolved": "https://registry.npmjs.org/cli-progress/-/cli-progress-3.12.0.tgz", "integrity": "sha512-tRkV3HJ1ASwm19THiiLIXLO7Im7wlTuKnvkYaTkyoAPefqjNg7W7DHKUlGRxy9vxDvbyCYQkQozvptuMkGCg8A==", + "dev": true, "dependencies": { "string-width": "^4.2.3" }, @@ -2714,6 +2450,7 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, "dependencies": { "color-name": "~1.1.4" }, @@ -2724,12 +2461,14 @@ "node_modules/color-name": { "version": "1.1.4", "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true }, "node_modules/combined-stream": { "version": "1.0.8", "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", + "dev": true, "dependencies": { "delayed-stream": "~1.0.0" }, @@ -2741,6 +2480,7 @@ "version": "11.1.0", "resolved": "https://registry.npmjs.org/commander/-/commander-11.1.0.tgz", "integrity": "sha512-yPVavfyCcRhmorC7rWlkHn15b4wDVgVmBA7kV4QVBsF7kv/9TKJAbAXVTxvTnwP8HHKjRCJDClKbciiYS7p0DQ==", + "dev": true, "engines": { "node": ">=16" } @@ -2831,16 +2571,11 @@ "node": ">= 10" } }, - "node_modules/create-require": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz", - "integrity": "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==", - "dev": true - }, "node_modules/cross-spawn": { "version": "7.0.3", "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", + "dev": true, "dependencies": { "path-key": "^3.1.0", "shebang-command": "^2.0.0", @@ -2889,17 +2624,9 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==", - "engines": { - "node": ">=0.4.0" - } - }, - "node_modules/diff": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", - "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==", "dev": true, "engines": { - "node": ">=0.3.1" + "node": ">=0.4.0" } }, "node_modules/diff-sequences": { @@ -2991,7 +2718,8 @@ "node_modules/eastasianwidth": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz", - "integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==" + "integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==", + "dev": true }, "node_modules/electron-to-chromium": { "version": "1.4.616", @@ -3002,7 +2730,8 @@ "node_modules/emoji-regex": { "version": "8.0.0", "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==" + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true }, "node_modules/end-of-stream": { "version": "1.4.4", @@ -3462,6 +3191,7 @@ "version": "1.15.5", "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.5.tgz", "integrity": "sha512-vSFWUON1B+yAw1VN4xMfxgn5fTUiaOzAJCKBwIIgT/+7CuGy9+r+5gITvP62j3RmaD5Ph65UaERdOSRGUzZtgw==", + "dev": true, "funding": [ { "type": "individual", @@ -3481,6 +3211,7 @@ "version": "3.1.1", "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.1.1.tgz", "integrity": "sha512-TMKDUnIte6bfb5nWv7V/caI169OHgvwjb7V4WkeUvbQQdjr5rWKqHFiKWb/fcOwB+CzBT+qbWjvj+DVwRskpIg==", + "dev": true, "dependencies": { "cross-spawn": "^7.0.0", "signal-exit": "^4.0.1" @@ -3496,6 +3227,7 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz", "integrity": "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==", + "dev": true, "dependencies": { "asynckit": "^0.4.0", "combined-stream": "^1.0.8", @@ -3562,6 +3294,7 @@ "version": "10.3.10", "resolved": "https://registry.npmjs.org/glob/-/glob-10.3.10.tgz", "integrity": "sha512-fa46+tv1Ak0UPK1TOy/pZrIybNNt4HCv7SDzwyfiOZkvZLEbjsZkJBPtDHVshZjbecAoAGSC20MjLDG/qr679g==", + "dev": true, "dependencies": { "foreground-child": "^3.1.0", "jackspeak": "^2.3.5", @@ -3595,6 +3328,7 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "dev": true, "dependencies": { "balanced-match": "^1.0.0" } @@ -3603,6 +3337,7 @@ "version": "9.0.3", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.3.tgz", "integrity": "sha512-RHiac9mvaRw0x3AYRgDC1CxAP7HTcNrrECeA8YYJeWnpo+2Q5CegtZjaotWTWxDG3UeGA1coE05iH1mPjT/2mg==", + "dev": true, "dependencies": { "brace-expansion": "^2.0.1" }, @@ -3822,6 +3557,7 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true, "engines": { "node": ">=8" } @@ -3865,7 +3601,8 @@ "node_modules/isexe": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==" + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", + "dev": true }, "node_modules/istanbul-lib-coverage": { "version": "3.2.2", @@ -3921,6 +3658,7 @@ "version": "2.3.6", "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-2.3.6.tgz", "integrity": "sha512-N3yCS/NegsOBokc8GAdM8UcmfsKiSS8cipheD/nivzr700H+nsMOxJjQnvwOcRYVuFkdH0wGUvW2WbXGmrZGbQ==", + "dev": true, "dependencies": { "@isaacs/cliui": "^8.0.2" }, @@ -4178,12 +3916,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/make-error": { - "version": "1.3.6", - "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz", - "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==", - "dev": true - }, "node_modules/merge-stream": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", @@ -4216,6 +3948,7 @@ "version": "1.52.0", "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", + "dev": true, "engines": { "node": ">= 0.6" } @@ -4224,6 +3957,7 @@ "version": "2.1.35", "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", + "dev": true, "dependencies": { "mime-db": "1.52.0" }, @@ -4256,6 +3990,7 @@ "version": "7.0.4", "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.0.4.tgz", "integrity": "sha512-jYofLM5Dam9279rdkWzqHozUo4ybjdZmCsDHePy5V/PbBcVMiSZR97gmAy45aqi8CK1lG2ECd356FU86avfwUQ==", + "dev": true, "engines": { "node": ">=16 || 14 >=14.17" } @@ -4509,6 +4244,7 @@ "version": "3.1.1", "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", + "dev": true, "engines": { "node": ">=8" } @@ -4523,6 +4259,7 @@ "version": "1.10.1", "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.10.1.tgz", "integrity": "sha512-MkhCqzzBEpPvxxQ71Md0b1Kk51W01lrYvlMzSUaIzNsODdd7mqhiimSZlr+VegAz5Z6Vzt9Xg2ttE//XBhH3EQ==", + "dev": true, "dependencies": { "lru-cache": "^9.1.1 || ^10.0.0", "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0" @@ -4538,6 +4275,7 @@ "version": "10.0.1", "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.0.1.tgz", "integrity": "sha512-IJ4uwUTi2qCccrioU6g9g/5rvvVl13bsdczUUcqbciD9iLr095yj8DQKdObriEvuNSx325N1rV1O0sJFszx75g==", + "dev": true, "engines": { "node": "14 || >=16.14" } @@ -4737,7 +4475,8 @@ "node_modules/proxy-from-env": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz", - "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==" + "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==", + "dev": true }, "node_modules/pump": { "version": "3.0.0", @@ -5164,6 +4903,7 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "dev": true, "dependencies": { "shebang-regex": "^3.0.0" }, @@ -5175,6 +4915,7 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", + "dev": true, "engines": { "node": ">=8" } @@ -5189,6 +4930,7 @@ "version": "4.1.0", "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", + "dev": true, "engines": { "node": ">=14" }, @@ -5334,6 +5076,7 @@ "version": "4.2.3", "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, "dependencies": { "emoji-regex": "^8.0.0", "is-fullwidth-code-point": "^3.0.0", @@ -5348,6 +5091,7 @@ "version": "4.2.3", "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, "dependencies": { "emoji-regex": "^8.0.0", "is-fullwidth-code-point": "^3.0.0", @@ -5361,6 +5105,7 @@ "version": "6.0.1", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, "dependencies": { "ansi-regex": "^5.0.1" }, @@ -5373,6 +5118,7 @@ "version": "6.0.1", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, "dependencies": { "ansi-regex": "^5.0.1" }, @@ -5632,49 +5378,6 @@ "typescript": ">=4.2.0" } }, - "node_modules/ts-node": { - "version": "10.9.2", - "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.9.2.tgz", - "integrity": "sha512-f0FFpIdcHgn8zcPSbf1dRevwt047YMnaiJM3u2w2RewrB+fob/zePZcrOyQoLMMO7aBIddLcQIEK5dYjkLnGrQ==", - "dev": true, - "dependencies": { - "@cspotcode/source-map-support": "^0.8.0", - "@tsconfig/node10": "^1.0.7", - "@tsconfig/node12": "^1.0.7", - "@tsconfig/node14": "^1.0.0", - "@tsconfig/node16": "^1.0.2", - "acorn": "^8.4.1", - "acorn-walk": "^8.1.1", - "arg": "^4.1.0", - "create-require": "^1.1.0", - "diff": "^4.0.1", - "make-error": "^1.1.1", - "v8-compile-cache-lib": "^3.0.1", - "yn": "3.1.1" - }, - "bin": { - "ts-node": "dist/bin.js", - "ts-node-cwd": "dist/bin-cwd.js", - "ts-node-esm": "dist/bin-esm.js", - "ts-node-script": "dist/bin-script.js", - "ts-node-transpile-only": "dist/bin-transpile.js", - "ts-script": "dist/bin-script-deprecated.js" - }, - "peerDependencies": { - "@swc/core": ">=1.2.50", - "@swc/wasm": ">=1.2.50", - "@types/node": "*", - "typescript": ">=2.7" - }, - "peerDependenciesMeta": { - "@swc/core": { - "optional": true - }, - "@swc/wasm": { - "optional": true - } - } - }, "node_modules/tslib": { "version": "2.6.2", "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.2.tgz", @@ -5790,12 +5493,6 @@ "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==", "dev": true }, - "node_modules/v8-compile-cache-lib": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz", - "integrity": "sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==", - "dev": true - }, "node_modules/v8-to-istanbul": { "version": "9.2.0", "resolved": "https://registry.npmjs.org/v8-to-istanbul/-/v8-to-istanbul-9.2.0.tgz", @@ -6105,6 +5802,7 @@ "version": "2.0.2", "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "dev": true, "dependencies": { "isexe": "^2.0.0" }, @@ -6135,6 +5833,7 @@ "version": "8.1.0", "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-8.1.0.tgz", "integrity": "sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==", + "dev": true, "dependencies": { "ansi-styles": "^6.1.0", "string-width": "^5.0.1", @@ -6152,6 +5851,7 @@ "version": "7.0.0", "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "dev": true, "dependencies": { "ansi-styles": "^4.0.0", "string-width": "^4.1.0", @@ -6168,6 +5868,7 @@ "version": "6.0.1", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.0.1.tgz", "integrity": "sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==", + "dev": true, "engines": { "node": ">=12" }, @@ -6179,6 +5880,7 @@ "version": "6.2.1", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz", "integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==", + "dev": true, "engines": { "node": ">=12" }, @@ -6189,12 +5891,14 @@ "node_modules/wrap-ansi/node_modules/emoji-regex": { "version": "9.2.2", "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz", - "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==" + "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==", + "dev": true }, "node_modules/wrap-ansi/node_modules/string-width": { "version": "5.1.2", "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz", "integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==", + "dev": true, "dependencies": { "eastasianwidth": "^0.2.0", "emoji-regex": "^9.2.2", @@ -6211,6 +5915,7 @@ "version": "7.1.0", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", + "dev": true, "dependencies": { "ansi-regex": "^6.0.1" }, @@ -6231,17 +5936,9 @@ "version": "2.3.4", "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.3.4.tgz", "integrity": "sha512-8aAvwVUSHpfEqTQ4w/KMlf3HcRdt50E5ODIQJBw1fQ5RL34xabzxtUlzTXVqc4rkZsPbvrXKWnABCD7kWSmocA==", - "engines": { - "node": ">= 14" - } - }, - "node_modules/yn": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz", - "integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==", "dev": true, "engines": { - "node": ">=6" + "node": ">= 14" } }, "node_modules/yocto-queue": { @@ -6507,27 +6204,6 @@ "integrity": "sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==", "dev": true }, - "@cspotcode/source-map-support": { - "version": "0.8.1", - "resolved": "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz", - "integrity": "sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==", - "dev": true, - "requires": { - "@jridgewell/trace-mapping": "0.3.9" - }, - "dependencies": { - "@jridgewell/trace-mapping": { - "version": "0.3.9", - "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.9.tgz", - "integrity": "sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==", - "dev": true, - "requires": { - "@jridgewell/resolve-uri": "^3.0.3", - "@jridgewell/sourcemap-codec": "^1.4.10" - } - } - } - }, "@esbuild/aix-ppc64": { "version": "0.19.12", "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.19.12.tgz", @@ -6762,6 +6438,7 @@ "version": "8.0.2", "resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-8.0.2.tgz", "integrity": "sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==", + "dev": true, "requires": { "string-width": "^5.1.2", "string-width-cjs": "npm:string-width@^4.2.0", @@ -6774,17 +6451,20 @@ "ansi-regex": { "version": "6.0.1", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.0.1.tgz", - "integrity": "sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==" + "integrity": "sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==", + "dev": true }, "emoji-regex": { "version": "9.2.2", "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz", - "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==" + "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==", + "dev": true }, "string-width": { "version": "5.1.2", "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz", "integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==", + "dev": true, "requires": { "eastasianwidth": "^0.2.0", "emoji-regex": "^9.2.2", @@ -6795,6 +6475,7 @@ "version": "7.1.0", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", + "dev": true, "requires": { "ansi-regex": "^6.0.1" } @@ -6885,6 +6566,7 @@ "version": "0.11.0", "resolved": "https://registry.npmjs.org/@pkgjs/parseargs/-/parseargs-0.11.0.tgz", "integrity": "sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==", + "dev": true, "optional": true }, "@pkgr/core": { @@ -6990,124 +6672,6 @@ "integrity": "sha512-+Fj43pSMwJs4KRrH/938Uf+uAELIgVBmQzg/q1YG10djyfA3TnrU8N8XzqCh/okZdszqBQTZf96idMfE5lnwTA==", "dev": true }, - "@swc/core": { - "version": "1.3.107", - "resolved": "https://registry.npmjs.org/@swc/core/-/core-1.3.107.tgz", - "integrity": "sha512-zKhqDyFcTsyLIYK1iEmavljZnf4CCor5pF52UzLAz4B6Nu/4GLU+2LQVAf+oRHjusG39PTPjd2AlRT3f3QWfsQ==", - "dev": true, - "optional": true, - "peer": true, - "requires": { - "@swc/core-darwin-arm64": "1.3.107", - "@swc/core-darwin-x64": "1.3.107", - "@swc/core-linux-arm-gnueabihf": "1.3.107", - "@swc/core-linux-arm64-gnu": "1.3.107", - "@swc/core-linux-arm64-musl": "1.3.107", - "@swc/core-linux-x64-gnu": "1.3.107", - "@swc/core-linux-x64-musl": "1.3.107", - "@swc/core-win32-arm64-msvc": "1.3.107", - "@swc/core-win32-ia32-msvc": "1.3.107", - "@swc/core-win32-x64-msvc": "1.3.107", - "@swc/counter": "^0.1.1", - "@swc/types": "^0.1.5" - } - }, - "@swc/core-darwin-arm64": { - "version": "1.3.107", - "resolved": "https://registry.npmjs.org/@swc/core-darwin-arm64/-/core-darwin-arm64-1.3.107.tgz", - "integrity": "sha512-47tD/5vSXWxPd0j/ZllyQUg4bqalbQTsmqSw0J4dDdS82MWqCAwUErUrAZPRjBkjNQ6Kmrf5rpCWaGTtPw+ngw==", - "dev": true, - "optional": true, - "peer": true - }, - "@swc/core-darwin-x64": { - "version": "1.3.107", - "resolved": "https://registry.npmjs.org/@swc/core-darwin-x64/-/core-darwin-x64-1.3.107.tgz", - "integrity": "sha512-hwiLJ2ulNkBGAh1m1eTfeY1417OAYbRGcb/iGsJ+LuVLvKAhU/itzsl535CvcwAlt2LayeCFfcI8gdeOLeZa9A==", - "dev": true, - "optional": true, - "peer": true - }, - "@swc/core-linux-arm-gnueabihf": { - "version": "1.3.107", - "resolved": "https://registry.npmjs.org/@swc/core-linux-arm-gnueabihf/-/core-linux-arm-gnueabihf-1.3.107.tgz", - "integrity": "sha512-I2wzcC0KXqh0OwymCmYwNRgZ9nxX7DWnOOStJXV3pS0uB83TXAkmqd7wvMBuIl9qu4Hfomi9aDM7IlEEn9tumQ==", - "dev": true, - "optional": true, - "peer": true - }, - "@swc/core-linux-arm64-gnu": { - "version": "1.3.107", - "resolved": "https://registry.npmjs.org/@swc/core-linux-arm64-gnu/-/core-linux-arm64-gnu-1.3.107.tgz", - "integrity": "sha512-HWgnn7JORYlOYnGsdunpSF8A+BCZKPLzLtEUA27/M/ZuANcMZabKL9Zurt7XQXq888uJFAt98Gy+59PU90aHKg==", - "dev": true, - "optional": true, - "peer": true - }, - "@swc/core-linux-arm64-musl": { - "version": "1.3.107", - "resolved": "https://registry.npmjs.org/@swc/core-linux-arm64-musl/-/core-linux-arm64-musl-1.3.107.tgz", - "integrity": "sha512-vfPF74cWfAm8hyhS8yvYI94ucMHIo8xIYU+oFOW9uvDlGQRgnUf/6DEVbLyt/3yfX5723Ln57U8uiMALbX5Pyw==", - "dev": true, - "optional": true, - "peer": true - }, - "@swc/core-linux-x64-gnu": { - "version": "1.3.107", - "resolved": "https://registry.npmjs.org/@swc/core-linux-x64-gnu/-/core-linux-x64-gnu-1.3.107.tgz", - "integrity": "sha512-uBVNhIg0ip8rH9OnOsCARUFZ3Mq3tbPHxtmWk9uAa5u8jQwGWeBx5+nTHpDOVd3YxKb6+5xDEI/edeeLpha/9g==", - "dev": true, - "optional": true, - "peer": true - }, - "@swc/core-linux-x64-musl": { - "version": "1.3.107", - "resolved": "https://registry.npmjs.org/@swc/core-linux-x64-musl/-/core-linux-x64-musl-1.3.107.tgz", - "integrity": "sha512-mvACkUvzSIB12q1H5JtabWATbk3AG+pQgXEN95AmEX2ZA5gbP9+B+mijsg7Sd/3tboHr7ZHLz/q3SHTvdFJrEw==", - "dev": true, - "optional": true, - "peer": true - }, - "@swc/core-win32-arm64-msvc": { - "version": "1.3.107", - "resolved": "https://registry.npmjs.org/@swc/core-win32-arm64-msvc/-/core-win32-arm64-msvc-1.3.107.tgz", - "integrity": "sha512-J3P14Ngy/1qtapzbguEH41kY109t6DFxfbK4Ntz9dOWNuVY3o9/RTB841ctnJk0ZHEG+BjfCJjsD2n8H5HcaOA==", - "dev": true, - "optional": true, - "peer": true - }, - "@swc/core-win32-ia32-msvc": { - "version": "1.3.107", - "resolved": "https://registry.npmjs.org/@swc/core-win32-ia32-msvc/-/core-win32-ia32-msvc-1.3.107.tgz", - "integrity": "sha512-ZBUtgyjTHlz8TPJh7kfwwwFma+ktr6OccB1oXC8fMSopD0AxVnQasgun3l3099wIsAB9eEsJDQ/3lDkOLs1gBA==", - "dev": true, - "optional": true, - "peer": true - }, - "@swc/core-win32-x64-msvc": { - "version": "1.3.107", - "resolved": "https://registry.npmjs.org/@swc/core-win32-x64-msvc/-/core-win32-x64-msvc-1.3.107.tgz", - "integrity": "sha512-Eyzo2XRqWOxqhE1gk9h7LWmUf4Bp4Xn2Ttb0ayAXFp6YSTxQIThXcT9kipXZqcpxcmDwoq8iWbbf2P8XL743EA==", - "dev": true, - "optional": true, - "peer": true - }, - "@swc/counter": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/@swc/counter/-/counter-0.1.2.tgz", - "integrity": "sha512-9F4ys4C74eSTEUNndnER3VJ15oru2NumfQxS8geE+f3eB5xvfxpWyqE5XlVnxb/R14uoXi6SLbBwwiDSkv+XEw==", - "dev": true, - "optional": true, - "peer": true - }, - "@swc/types": { - "version": "0.1.5", - "resolved": "https://registry.npmjs.org/@swc/types/-/types-0.1.5.tgz", - "integrity": "sha512-myfUej5naTBWnqOCc/MdVOLVjXUXtIA+NpDrDBKJtLLg2shUjBu3cZmB/85RyitKc55+lUUyl7oRfLOvkr2hsw==", - "dev": true, - "optional": true, - "peer": true - }, "@testcontainers/postgresql": { "version": "10.6.0", "resolved": "https://registry.npmjs.org/@testcontainers/postgresql/-/postgresql-10.6.0.tgz", @@ -7117,30 +6681,6 @@ "testcontainers": "^10.6.0" } }, - "@tsconfig/node10": { - "version": "1.0.9", - "resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.9.tgz", - "integrity": "sha512-jNsYVVxU8v5g43Erja32laIDHXeoNvFEpX33OK4d6hljo3jDhCBDhx5dhCCTMWUojscpAagGiRkBKxpdl9fxqA==", - "dev": true - }, - "@tsconfig/node12": { - "version": "1.0.11", - "resolved": "https://registry.npmjs.org/@tsconfig/node12/-/node12-1.0.11.tgz", - "integrity": "sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag==", - "dev": true - }, - "@tsconfig/node14": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/@tsconfig/node14/-/node14-1.0.3.tgz", - "integrity": "sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow==", - "dev": true - }, - "@tsconfig/node16": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/@tsconfig/node16/-/node16-1.0.4.tgz", - "integrity": "sha512-vxhUy4J8lyeyinH7Azl1pdd43GJhZH/tP2weN8TntQblOY+A0XbT8DJk1/oCPuOOyg/Ja757rG0CgHcWC8OfMA==", - "dev": true - }, "@types/byte-size": { "version": "8.1.2", "resolved": "https://registry.npmjs.org/@types/byte-size/-/byte-size-8.1.2.tgz", @@ -7656,12 +7196,14 @@ "ansi-regex": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==" + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true }, "ansi-styles": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, "requires": { "color-convert": "^2.0.1" } @@ -7745,12 +7287,6 @@ } } }, - "arg": { - "version": "4.1.3", - "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz", - "integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==", - "dev": true - }, "argparse": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", @@ -7793,12 +7329,14 @@ "asynckit": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", - "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==" + "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==", + "dev": true }, "axios": { "version": "1.6.7", "resolved": "https://registry.npmjs.org/axios/-/axios-1.6.7.tgz", "integrity": "sha512-/hDJGff6/c7u0hDkvkGxR/oy6CbCs8ziCsC7SqmhjfozqiJGc8Z11wrv9z9lYfY4K8l+H9TpjcMDX0xOZmx+RA==", + "dev": true, "requires": { "follow-redirects": "^1.15.4", "form-data": "^4.0.0", @@ -7814,7 +7352,8 @@ "balanced-match": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", - "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==" + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", + "dev": true }, "base64-js": { "version": "1.5.1", @@ -7911,7 +7450,8 @@ "byte-size": { "version": "8.1.1", "resolved": "https://registry.npmjs.org/byte-size/-/byte-size-8.1.1.tgz", - "integrity": "sha512-tUkzZWK0M/qdoLEqikxBWe4kumyuwjl3HO6zHTr4yEI23EojPtLYXdG1+AQY7MN0cGyNDvEaJ8wiYQm6P2bPxg==" + "integrity": "sha512-tUkzZWK0M/qdoLEqikxBWe4kumyuwjl3HO6zHTr4yEI23EojPtLYXdG1+AQY7MN0cGyNDvEaJ8wiYQm6P2bPxg==", + "dev": true }, "cac": { "version": "6.7.14", @@ -7992,6 +7532,7 @@ "version": "3.12.0", "resolved": "https://registry.npmjs.org/cli-progress/-/cli-progress-3.12.0.tgz", "integrity": "sha512-tRkV3HJ1ASwm19THiiLIXLO7Im7wlTuKnvkYaTkyoAPefqjNg7W7DHKUlGRxy9vxDvbyCYQkQozvptuMkGCg8A==", + "dev": true, "requires": { "string-width": "^4.2.3" } @@ -8000,6 +7541,7 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, "requires": { "color-name": "~1.1.4" } @@ -8007,12 +7549,14 @@ "color-name": { "version": "1.1.4", "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true }, "combined-stream": { "version": "1.0.8", "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", + "dev": true, "requires": { "delayed-stream": "~1.0.0" } @@ -8020,7 +7564,8 @@ "commander": { "version": "11.1.0", "resolved": "https://registry.npmjs.org/commander/-/commander-11.1.0.tgz", - "integrity": "sha512-yPVavfyCcRhmorC7rWlkHn15b4wDVgVmBA7kV4QVBsF7kv/9TKJAbAXVTxvTnwP8HHKjRCJDClKbciiYS7p0DQ==" + "integrity": "sha512-yPVavfyCcRhmorC7rWlkHn15b4wDVgVmBA7kV4QVBsF7kv/9TKJAbAXVTxvTnwP8HHKjRCJDClKbciiYS7p0DQ==", + "dev": true }, "compress-commons": { "version": "4.1.2", @@ -8088,16 +7633,11 @@ "readable-stream": "^3.4.0" } }, - "create-require": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz", - "integrity": "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==", - "dev": true - }, "cross-spawn": { "version": "7.0.3", "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", + "dev": true, "requires": { "path-key": "^3.1.0", "shebang-command": "^2.0.0", @@ -8131,12 +7671,7 @@ "delayed-stream": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", - "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==" - }, - "diff": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", - "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==", + "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==", "dev": true }, "diff-sequences": { @@ -8212,7 +7747,8 @@ "eastasianwidth": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz", - "integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==" + "integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==", + "dev": true }, "electron-to-chromium": { "version": "1.4.616", @@ -8223,7 +7759,8 @@ "emoji-regex": { "version": "8.0.0", "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==" + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true }, "end-of-stream": { "version": "1.4.4", @@ -8567,12 +8104,14 @@ "follow-redirects": { "version": "1.15.5", "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.5.tgz", - "integrity": "sha512-vSFWUON1B+yAw1VN4xMfxgn5fTUiaOzAJCKBwIIgT/+7CuGy9+r+5gITvP62j3RmaD5Ph65UaERdOSRGUzZtgw==" + "integrity": "sha512-vSFWUON1B+yAw1VN4xMfxgn5fTUiaOzAJCKBwIIgT/+7CuGy9+r+5gITvP62j3RmaD5Ph65UaERdOSRGUzZtgw==", + "dev": true }, "foreground-child": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.1.1.tgz", "integrity": "sha512-TMKDUnIte6bfb5nWv7V/caI169OHgvwjb7V4WkeUvbQQdjr5rWKqHFiKWb/fcOwB+CzBT+qbWjvj+DVwRskpIg==", + "dev": true, "requires": { "cross-spawn": "^7.0.0", "signal-exit": "^4.0.1" @@ -8582,6 +8121,7 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz", "integrity": "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==", + "dev": true, "requires": { "asynckit": "^0.4.0", "combined-stream": "^1.0.8", @@ -8629,6 +8169,7 @@ "version": "10.3.10", "resolved": "https://registry.npmjs.org/glob/-/glob-10.3.10.tgz", "integrity": "sha512-fa46+tv1Ak0UPK1TOy/pZrIybNNt4HCv7SDzwyfiOZkvZLEbjsZkJBPtDHVshZjbecAoAGSC20MjLDG/qr679g==", + "dev": true, "requires": { "foreground-child": "^3.1.0", "jackspeak": "^2.3.5", @@ -8641,6 +8182,7 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "dev": true, "requires": { "balanced-match": "^1.0.0" } @@ -8649,6 +8191,7 @@ "version": "9.0.3", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.3.tgz", "integrity": "sha512-RHiac9mvaRw0x3AYRgDC1CxAP7HTcNrrECeA8YYJeWnpo+2Q5CegtZjaotWTWxDG3UeGA1coE05iH1mPjT/2mg==", + "dev": true, "requires": { "brace-expansion": "^2.0.1" } @@ -8903,7 +8446,8 @@ "is-fullwidth-code-point": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", - "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==" + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true }, "is-glob": { "version": "4.0.3", @@ -8935,7 +8479,8 @@ "isexe": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==" + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", + "dev": true }, "istanbul-lib-coverage": { "version": "3.2.2", @@ -8979,6 +8524,7 @@ "version": "2.3.6", "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-2.3.6.tgz", "integrity": "sha512-N3yCS/NegsOBokc8GAdM8UcmfsKiSS8cipheD/nivzr700H+nsMOxJjQnvwOcRYVuFkdH0wGUvW2WbXGmrZGbQ==", + "dev": true, "requires": { "@isaacs/cliui": "^8.0.2", "@pkgjs/parseargs": "^0.11.0" @@ -9194,12 +8740,6 @@ "semver": "^7.5.3" } }, - "make-error": { - "version": "1.3.6", - "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz", - "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==", - "dev": true - }, "merge-stream": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", @@ -9225,12 +8765,14 @@ "mime-db": { "version": "1.52.0", "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", - "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==" + "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", + "dev": true }, "mime-types": { "version": "2.1.35", "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", + "dev": true, "requires": { "mime-db": "1.52.0" } @@ -9253,7 +8795,8 @@ "minipass": { "version": "7.0.4", "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.0.4.tgz", - "integrity": "sha512-jYofLM5Dam9279rdkWzqHozUo4ybjdZmCsDHePy5V/PbBcVMiSZR97gmAy45aqi8CK1lG2ECd356FU86avfwUQ==" + "integrity": "sha512-jYofLM5Dam9279rdkWzqHozUo4ybjdZmCsDHePy5V/PbBcVMiSZR97gmAy45aqi8CK1lG2ECd356FU86avfwUQ==", + "dev": true }, "mkdirp": { "version": "1.0.4", @@ -9434,7 +8977,8 @@ "path-key": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", - "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==" + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", + "dev": true }, "path-parse": { "version": "1.0.7", @@ -9446,6 +8990,7 @@ "version": "1.10.1", "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.10.1.tgz", "integrity": "sha512-MkhCqzzBEpPvxxQ71Md0b1Kk51W01lrYvlMzSUaIzNsODdd7mqhiimSZlr+VegAz5Z6Vzt9Xg2ttE//XBhH3EQ==", + "dev": true, "requires": { "lru-cache": "^9.1.1 || ^10.0.0", "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0" @@ -9454,7 +8999,8 @@ "lru-cache": { "version": "10.0.1", "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.0.1.tgz", - "integrity": "sha512-IJ4uwUTi2qCccrioU6g9g/5rvvVl13bsdczUUcqbciD9iLr095yj8DQKdObriEvuNSx325N1rV1O0sJFszx75g==" + "integrity": "sha512-IJ4uwUTi2qCccrioU6g9g/5rvvVl13bsdczUUcqbciD9iLr095yj8DQKdObriEvuNSx325N1rV1O0sJFszx75g==", + "dev": true } } }, @@ -9594,7 +9140,8 @@ "proxy-from-env": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz", - "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==" + "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==", + "dev": true }, "pump": { "version": "3.0.0", @@ -9897,6 +9444,7 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "dev": true, "requires": { "shebang-regex": "^3.0.0" } @@ -9904,7 +9452,8 @@ "shebang-regex": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", - "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==" + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", + "dev": true }, "siginfo": { "version": "2.0.0", @@ -9915,7 +9464,8 @@ "signal-exit": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", - "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==" + "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", + "dev": true }, "slash": { "version": "3.0.0", @@ -10042,6 +9592,7 @@ "version": "4.2.3", "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, "requires": { "emoji-regex": "^8.0.0", "is-fullwidth-code-point": "^3.0.0", @@ -10052,6 +9603,7 @@ "version": "npm:string-width@4.2.3", "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, "requires": { "emoji-regex": "^8.0.0", "is-fullwidth-code-point": "^3.0.0", @@ -10062,6 +9614,7 @@ "version": "6.0.1", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, "requires": { "ansi-regex": "^5.0.1" } @@ -10070,6 +9623,7 @@ "version": "npm:strip-ansi@6.0.1", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, "requires": { "ansi-regex": "^5.0.1" } @@ -10271,27 +9825,6 @@ "dev": true, "requires": {} }, - "ts-node": { - "version": "10.9.2", - "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.9.2.tgz", - "integrity": "sha512-f0FFpIdcHgn8zcPSbf1dRevwt047YMnaiJM3u2w2RewrB+fob/zePZcrOyQoLMMO7aBIddLcQIEK5dYjkLnGrQ==", - "dev": true, - "requires": { - "@cspotcode/source-map-support": "^0.8.0", - "@tsconfig/node10": "^1.0.7", - "@tsconfig/node12": "^1.0.7", - "@tsconfig/node14": "^1.0.0", - "@tsconfig/node16": "^1.0.2", - "acorn": "^8.4.1", - "acorn-walk": "^8.1.1", - "arg": "^4.1.0", - "create-require": "^1.1.0", - "diff": "^4.0.1", - "make-error": "^1.1.1", - "v8-compile-cache-lib": "^3.0.1", - "yn": "3.1.1" - } - }, "tslib": { "version": "2.6.2", "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.2.tgz", @@ -10368,12 +9901,6 @@ "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==", "dev": true }, - "v8-compile-cache-lib": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz", - "integrity": "sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==", - "dev": true - }, "v8-to-istanbul": { "version": "9.2.0", "resolved": "https://registry.npmjs.org/v8-to-istanbul/-/v8-to-istanbul-9.2.0.tgz", @@ -10542,6 +10069,7 @@ "version": "2.0.2", "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "dev": true, "requires": { "isexe": "^2.0.0" } @@ -10560,6 +10088,7 @@ "version": "8.1.0", "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-8.1.0.tgz", "integrity": "sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==", + "dev": true, "requires": { "ansi-styles": "^6.1.0", "string-width": "^5.0.1", @@ -10569,22 +10098,26 @@ "ansi-regex": { "version": "6.0.1", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.0.1.tgz", - "integrity": "sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==" + "integrity": "sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==", + "dev": true }, "ansi-styles": { "version": "6.2.1", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz", - "integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==" + "integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==", + "dev": true }, "emoji-regex": { "version": "9.2.2", "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz", - "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==" + "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==", + "dev": true }, "string-width": { "version": "5.1.2", "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz", "integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==", + "dev": true, "requires": { "eastasianwidth": "^0.2.0", "emoji-regex": "^9.2.2", @@ -10595,6 +10128,7 @@ "version": "7.1.0", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", + "dev": true, "requires": { "ansi-regex": "^6.0.1" } @@ -10605,6 +10139,7 @@ "version": "npm:wrap-ansi@7.0.0", "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "dev": true, "requires": { "ansi-styles": "^4.0.0", "string-width": "^4.1.0", @@ -10620,12 +10155,7 @@ "yaml": { "version": "2.3.4", "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.3.4.tgz", - "integrity": "sha512-8aAvwVUSHpfEqTQ4w/KMlf3HcRdt50E5ODIQJBw1fQ5RL34xabzxtUlzTXVqc4rkZsPbvrXKWnABCD7kWSmocA==" - }, - "yn": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz", - "integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==", + "integrity": "sha512-8aAvwVUSHpfEqTQ4w/KMlf3HcRdt50E5ODIQJBw1fQ5RL34xabzxtUlzTXVqc4rkZsPbvrXKWnABCD7kWSmocA==", "dev": true }, "yocto-queue": { diff --git a/cli/package.json b/cli/package.json index 64691b5cdd..a4bb184a44 100644 --- a/cli/package.json +++ b/cli/package.json @@ -12,16 +12,8 @@ "immich", "cli" ], - "dependencies": { - "@immich/sdk": "file:../open-api/typescript-sdk", - "axios": "^1.6.7", - "byte-size": "^8.1.1", - "cli-progress": "^3.12.0", - "commander": "^11.0.0", - "glob": "^10.3.1", - "yaml": "^2.3.1" - }, "devDependencies": { + "@immich/sdk": "file:../open-api/typescript-sdk", "@testcontainers/postgresql": "^10.4.0", "@types/byte-size": "^8.1.0", "@types/cli-progress": "^3.11.0", @@ -30,19 +22,24 @@ "@typescript-eslint/eslint-plugin": "^6.4.1", "@typescript-eslint/parser": "^6.4.1", "@vitest/coverage-v8": "^1.2.2", + "axios": "^1.6.7", + "byte-size": "^8.1.1", + "cli-progress": "^3.12.0", + "commander": "^11.0.0", "eslint": "^8.56.0", "eslint-config-prettier": "^9.1.0", "eslint-plugin-prettier": "^5.1.3", "eslint-plugin-unicorn": "^50.0.1", + "glob": "^10.3.1", "immich": "file:../server", "mock-fs": "^5.2.0", - "ts-node": "^10.9.1", - "tslib": "^2.5.3", "typescript": "^5.3.3", - "vitest": "^1.2.1" + "vite": "^5.0.12", + "vitest": "^1.2.1", + "yaml": "^2.3.1" }, "scripts": { - "build": "tsc --project tsconfig.build.json", + "build": "vite build", "lint": "eslint \"src/**/*.ts\" \"test/**/*.ts\" --max-warnings 0", "lint:fix": "npm run lint -- --fix", "prepack": "npm run build", diff --git a/cli/tsconfig.build.json b/cli/tsconfig.build.json deleted file mode 100644 index 0d7cd0873c..0000000000 --- a/cli/tsconfig.build.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "extends": "./tsconfig.json", - "exclude": ["dist", "node_modules", "upload", "test", "**/*spec.ts"] -} diff --git a/cli/vite.config.ts b/cli/vite.config.ts new file mode 100644 index 0000000000..89ee3a3d3e --- /dev/null +++ b/cli/vite.config.ts @@ -0,0 +1,17 @@ +import { defineConfig } from 'vite'; + +export default defineConfig({ + build: { + rollupOptions: { + input: 'src/index.ts', + output: { + dir: 'dist', + }, + }, + ssr: true, + }, + ssr: { + // bundle everything except for Node built-ins + noExternal: /^(?!node:).*$/, + }, +}); From 5061c35c8d0668eba58a8aeb31bc6323d1747828 Mon Sep 17 00:00:00 2001 From: rovo89 Date: Sun, 4 Feb 2024 21:35:13 +0100 Subject: [PATCH 007/104] feat(mobile): Add support for Basic Authentication (#6840) --- .../lib/modules/album/ui/album_thumbnail_listtile.dart | 2 +- .../lib/modules/asset_viewer/views/gallery_viewer.dart | 6 ++---- .../modules/asset_viewer/views/video_viewer_page.dart | 8 ++++---- mobile/lib/modules/backup/services/backup.service.dart | 3 +-- .../map/widgets/positioned_asset_marker_icon.dart | 3 +-- mobile/lib/modules/memories/ui/memory_card.dart | 4 ++-- mobile/lib/modules/search/ui/curated_people_row.dart | 2 +- mobile/lib/modules/search/ui/thumbnail_with_info.dart | 3 +-- .../lib/modules/search/views/person_result_page.dart | 3 +-- mobile/lib/shared/providers/websocket.provider.dart | 8 +++++++- mobile/lib/shared/services/api.service.dart | 10 +++++----- mobile/lib/shared/ui/immich_image.dart | 10 +++++----- mobile/lib/shared/ui/user_avatar.dart | 2 +- mobile/lib/shared/ui/user_circle_avatar.dart | 2 +- 14 files changed, 33 insertions(+), 33 deletions(-) diff --git a/mobile/lib/modules/album/ui/album_thumbnail_listtile.dart b/mobile/lib/modules/album/ui/album_thumbnail_listtile.dart index 107d08b1fb..f2f465f29e 100644 --- a/mobile/lib/modules/album/ui/album_thumbnail_listtile.dart +++ b/mobile/lib/modules/album/ui/album_thumbnail_listtile.dart @@ -49,7 +49,7 @@ class AlbumThumbnailListTile extends StatelessWidget { type: ThumbnailFormat.WEBP, ), httpHeaders: { - "Authorization": "Bearer ${Store.get(StoreKey.accessToken)}", + "x-immich-user-token": Store.get(StoreKey.accessToken), }, cacheKey: getAlbumThumbNailCacheKey(album, type: ThumbnailFormat.WEBP), errorWidget: (context, url, error) => diff --git a/mobile/lib/modules/asset_viewer/views/gallery_viewer.dart b/mobile/lib/modules/asset_viewer/views/gallery_viewer.dart index ac6bd1fc85..1903a7f19c 100644 --- a/mobile/lib/modules/asset_viewer/views/gallery_viewer.dart +++ b/mobile/lib/modules/asset_viewer/views/gallery_viewer.dart @@ -78,8 +78,7 @@ class GalleryViewerPage extends HookConsumerWidget { final isPlayingMotionVideo = useState(false); final isPlayingVideo = useState(false); Offset? localPosition; - final authToken = 'Bearer ${Store.get(StoreKey.accessToken)}'; - final header = {"Authorization": authToken}; + final header = {"x-immich-user-token": Store.get(StoreKey.accessToken)}; final currentIndex = useState(initialIndex); final currentAsset = loadAsset(currentIndex.value); final isTrashEnabled = @@ -524,8 +523,7 @@ class GalleryViewerPage extends HookConsumerWidget { imageUrl: '${Store.get(StoreKey.serverEndpoint)}/asset/thumbnail/$assetId', httpHeaders: { - "Authorization": - "Bearer ${Store.get(StoreKey.accessToken)}", + "x-immich-user-token": Store.get(StoreKey.accessToken), }, errorWidget: (context, url, error) => const Icon(Icons.image_not_supported_outlined), diff --git a/mobile/lib/modules/asset_viewer/views/video_viewer_page.dart b/mobile/lib/modules/asset_viewer/views/video_viewer_page.dart index 1df312095a..8257f28578 100644 --- a/mobile/lib/modules/asset_viewer/views/video_viewer_page.dart +++ b/mobile/lib/modules/asset_viewer/views/video_viewer_page.dart @@ -68,7 +68,7 @@ class VideoViewerPage extends HookConsumerWidget { children: [ VideoPlayer( url: videoUrl, - jwtToken: Store.get(StoreKey.accessToken), + accessToken: Store.get(StoreKey.accessToken), isMotionVideo: isMotionVideo, onVideoEnded: onVideoEnded, onPaused: onPaused, @@ -99,7 +99,7 @@ final _fileFamily = class VideoPlayer extends StatefulWidget { final String? url; - final String? jwtToken; + final String? accessToken; final File? file; final bool isMotionVideo; final VoidCallback onVideoEnded; @@ -114,7 +114,7 @@ class VideoPlayer extends StatefulWidget { const VideoPlayer({ super.key, this.url, - this.jwtToken, + this.accessToken, this.file, required this.onVideoEnded, required this.isMotionVideo, @@ -160,7 +160,7 @@ class _VideoPlayerState extends State { videoPlayerController = widget.file == null ? VideoPlayerController.networkUrl( Uri.parse(widget.url!), - httpHeaders: {"Authorization": "Bearer ${widget.jwtToken}"}, + httpHeaders: {"x-immich-user-token": widget.accessToken ?? ""}, ) : VideoPlayerController.file(widget.file!); diff --git a/mobile/lib/modules/backup/services/backup.service.dart b/mobile/lib/modules/backup/services/backup.service.dart index fd92222ef5..48d6f71cf9 100644 --- a/mobile/lib/modules/backup/services/backup.service.dart +++ b/mobile/lib/modules/backup/services/backup.service.dart @@ -302,8 +302,7 @@ class BackupService { onProgress: ((bytes, totalBytes) => uploadProgressCb(bytes, totalBytes)), ); - req.headers["Authorization"] = - "Bearer ${Store.get(StoreKey.accessToken)}"; + req.headers["x-immich-user-token"] = Store.get(StoreKey.accessToken); req.headers["Transfer-Encoding"] = "chunked"; req.fields['deviceAssetId'] = entity.id; diff --git a/mobile/lib/modules/map/widgets/positioned_asset_marker_icon.dart b/mobile/lib/modules/map/widgets/positioned_asset_marker_icon.dart index cec5114ee1..e7cd6f6227 100644 --- a/mobile/lib/modules/map/widgets/positioned_asset_marker_icon.dart +++ b/mobile/lib/modules/map/widgets/positioned_asset_marker_icon.dart @@ -89,8 +89,7 @@ class _AssetMarkerIcon extends StatelessWidget { imageUrl, cacheKey: cacheKey, headers: { - "Authorization": - "Bearer ${Store.get(StoreKey.accessToken)}", + "x-immich-user-token": Store.get(StoreKey.accessToken), }, errorListener: (_) => const Icon(Icons.image_not_supported_outlined), diff --git a/mobile/lib/modules/memories/ui/memory_card.dart b/mobile/lib/modules/memories/ui/memory_card.dart index d9ccaed39f..883c5b3866 100644 --- a/mobile/lib/modules/memories/ui/memory_card.dart +++ b/mobile/lib/modules/memories/ui/memory_card.dart @@ -27,7 +27,7 @@ class MemoryCard extends StatelessWidget { super.key, }); - String get authToken => 'Bearer ${Store.get(StoreKey.accessToken)}'; + String get accessToken => Store.get(StoreKey.accessToken); @override Widget build(BuildContext context) { @@ -55,7 +55,7 @@ class MemoryCard extends StatelessWidget { cacheKey: getThumbnailCacheKey( asset, ), - headers: {"Authorization": authToken}, + headers: {"x-immich-user-token": accessToken}, ), fit: BoxFit.cover, ), diff --git a/mobile/lib/modules/search/ui/curated_people_row.dart b/mobile/lib/modules/search/ui/curated_people_row.dart index e838c59e12..aa3403f2a1 100644 --- a/mobile/lib/modules/search/ui/curated_people_row.dart +++ b/mobile/lib/modules/search/ui/curated_people_row.dart @@ -51,7 +51,7 @@ class CuratedPeopleRow extends StatelessWidget { itemBuilder: (context, index) { final person = content[index]; final headers = { - "Authorization": "Bearer ${Store.get(StoreKey.accessToken)}", + "x-immich-user-token": Store.get(StoreKey.accessToken), }; return Padding( padding: const EdgeInsets.only(right: 18.0), diff --git a/mobile/lib/modules/search/ui/thumbnail_with_info.dart b/mobile/lib/modules/search/ui/thumbnail_with_info.dart index e9be93ad49..6d447526ce 100644 --- a/mobile/lib/modules/search/ui/thumbnail_with_info.dart +++ b/mobile/lib/modules/search/ui/thumbnail_with_info.dart @@ -46,8 +46,7 @@ class ThumbnailWithInfo extends StatelessWidget { fit: BoxFit.cover, imageUrl: imageUrl!, httpHeaders: { - "Authorization": - "Bearer ${Store.get(StoreKey.accessToken)}", + "x-immich-user-token": Store.get(StoreKey.accessToken), }, errorWidget: (context, url, error) => const Icon(Icons.image_not_supported_outlined), diff --git a/mobile/lib/modules/search/views/person_result_page.dart b/mobile/lib/modules/search/views/person_result_page.dart index 8e09f47c34..0b7eeea51d 100644 --- a/mobile/lib/modules/search/views/person_result_page.dart +++ b/mobile/lib/modules/search/views/person_result_page.dart @@ -123,8 +123,7 @@ class PersonResultPage extends HookConsumerWidget { backgroundImage: NetworkImage( getFaceThumbnailUrl(personId), headers: { - "Authorization": - "Bearer ${Store.get(StoreKey.accessToken)}", + "x-immich-user-token": Store.get(StoreKey.accessToken), }, ), ), diff --git a/mobile/lib/shared/providers/websocket.provider.dart b/mobile/lib/shared/providers/websocket.provider.dart index c78777da5a..6b12916d27 100644 --- a/mobile/lib/shared/providers/websocket.provider.dart +++ b/mobile/lib/shared/providers/websocket.provider.dart @@ -1,3 +1,5 @@ +import 'dart:convert'; + import 'package:collection/collection.dart'; import 'package:flutter/foundation.dart'; import 'package:flutter/widgets.dart'; @@ -106,6 +108,10 @@ class WebsocketNotifier extends StateNotifier { final accessToken = Store.get(StoreKey.accessToken); try { final endpoint = Uri.parse(Store.get(StoreKey.serverEndpoint)); + final headers = {"x-immich-user-token": accessToken}; + if (endpoint.userInfo.isNotEmpty) { + headers["Authorization"] = "Basic ${base64.encode(utf8.encode(endpoint.userInfo))}"; + } debugPrint("Attempting to connect to websocket"); // Configure socket transports must be specified @@ -118,7 +124,7 @@ class WebsocketNotifier extends StateNotifier { .enableForceNew() .enableForceNewConnection() .enableAutoConnect() - .setExtraHeaders({"Authorization": "Bearer $accessToken"}) + .setExtraHeaders(headers) .build(), ); diff --git a/mobile/lib/shared/services/api.service.dart b/mobile/lib/shared/services/api.service.dart index 656de826cf..2df1ec857f 100644 --- a/mobile/lib/shared/services/api.service.dart +++ b/mobile/lib/shared/services/api.service.dart @@ -31,12 +31,12 @@ class ApiService { setEndpoint(endpoint); } } - String? _authToken; + String? _accessToken; setEndpoint(String endpoint) { _apiClient = ApiClient(basePath: endpoint); - if (_authToken != null) { - setAccessToken(_authToken!); + if (_accessToken != null) { + setAccessToken(_accessToken!); } userApi = UserApi(_apiClient); authenticationApi = AuthenticationApi(_apiClient); @@ -134,8 +134,8 @@ class ApiService { } setAccessToken(String accessToken) { - _authToken = accessToken; - _apiClient.addDefaultHeader('Authorization', 'Bearer $accessToken'); + _accessToken = accessToken; + _apiClient.addDefaultHeader('x-immich-user-token', accessToken); } ApiClient get apiClient => _apiClient; diff --git a/mobile/lib/shared/ui/immich_image.dart b/mobile/lib/shared/ui/immich_image.dart index 575a841f11..18f5147e83 100644 --- a/mobile/lib/shared/ui/immich_image.dart +++ b/mobile/lib/shared/ui/immich_image.dart @@ -95,11 +95,11 @@ class ImmichImage extends StatelessWidget { }, ); } - final String? token = Store.get(StoreKey.accessToken); + final String? accessToken = Store.get(StoreKey.accessToken); final String thumbnailRequestUrl = getThumbnailUrl(asset, type: type); return CachedNetworkImage( imageUrl: thumbnailRequestUrl, - httpHeaders: {"Authorization": "Bearer $token"}, + httpHeaders: {"x-immich-user-token": accessToken ?? ""}, cacheKey: getThumbnailCacheKey(asset, type: type), width: width, height: height, @@ -177,7 +177,7 @@ class ImmichImage extends StatelessWidget { getThumbnailUrlForRemoteId(assetId, type: type), cacheKey: getThumbnailCacheKeyForRemoteId(assetId, type: type), headers: { - "Authorization": 'Bearer ${Store.get(StoreKey.accessToken)}', + "x-immich-user-token": Store.get(StoreKey.accessToken), }, ); @@ -195,10 +195,10 @@ class ImmichImage extends StatelessWidget { context, ); } else { - final authToken = 'Bearer ${Store.get(StoreKey.accessToken)}'; + final accessToken = Store.get(StoreKey.accessToken); // Precache the remote image since we are not using local images return precacheImage( - remoteThumbnailProvider(asset, type, {"Authorization": authToken}), + remoteThumbnailProvider(asset, type, {"x-immich-user-token": accessToken}), context, ); } diff --git a/mobile/lib/shared/ui/user_avatar.dart b/mobile/lib/shared/ui/user_avatar.dart index 95f76de43f..68ed2edbdc 100644 --- a/mobile/lib/shared/ui/user_avatar.dart +++ b/mobile/lib/shared/ui/user_avatar.dart @@ -13,7 +13,7 @@ Widget userAvatar(BuildContext context, User u, {double? radius}) { backgroundColor: context.primaryColor.withAlpha(50), foregroundImage: CachedNetworkImageProvider( url, - headers: {"Authorization": "Bearer ${Store.get(StoreKey.accessToken)}"}, + headers: {"x-immich-user-token": Store.get(StoreKey.accessToken)}, cacheKey: "user-${u.id}-profile", ), // silence errors if user has no profile image, use initials as fallback diff --git a/mobile/lib/shared/ui/user_circle_avatar.dart b/mobile/lib/shared/ui/user_circle_avatar.dart index 3dc0e65c1b..103d8970e3 100644 --- a/mobile/lib/shared/ui/user_circle_avatar.dart +++ b/mobile/lib/shared/ui/user_circle_avatar.dart @@ -51,7 +51,7 @@ class UserCircleAvatar extends ConsumerWidget { placeholder: (_, __) => Image.memory(kTransparentImage), imageUrl: profileImageUrl, httpHeaders: { - "Authorization": "Bearer ${Store.get(StoreKey.accessToken)}", + "x-immich-user-token": Store.get(StoreKey.accessToken), }, fadeInDuration: const Duration(milliseconds: 300), errorWidget: (context, error, stackTrace) => textIcon, From f4ab5d3ff75396709a25fcc28604539d9622c251 Mon Sep 17 00:00:00 2001 From: Emanuel Bennici Date: Mon, 5 Feb 2024 04:02:51 +0100 Subject: [PATCH 008/104] feat(mobile): Add haptic feedback to asset grid (#5344) Add a haptic feedback when jumping from one month to another in the asset grid view. The feedback is similar to the one implemented in the Google Photos app. --- .../ui/asset_grid/immich_asset_grid_view.dart | 47 ++++++++++++++++++- 1 file changed, 45 insertions(+), 2 deletions(-) diff --git a/mobile/lib/modules/home/ui/asset_grid/immich_asset_grid_view.dart b/mobile/lib/modules/home/ui/asset_grid/immich_asset_grid_view.dart index 7087456c97..bd671ca6ba 100644 --- a/mobile/lib/modules/home/ui/asset_grid/immich_asset_grid_view.dart +++ b/mobile/lib/modules/home/ui/asset_grid/immich_asset_grid_view.dart @@ -1,19 +1,22 @@ import 'dart:collection'; +import 'dart:developer'; import 'dart:math'; import 'package:collection/collection.dart'; import 'package:easy_localization/easy_localization.dart'; import 'package:flutter/material.dart'; +import 'package:flutter/services.dart'; import 'package:immich_mobile/extensions/build_context_extensions.dart'; +import 'package:immich_mobile/extensions/collection_extensions.dart'; import 'package:immich_mobile/modules/asset_viewer/providers/scroll_notifier.provider.dart'; import 'package:immich_mobile/modules/home/ui/asset_grid/thumbnail_image.dart'; import 'package:immich_mobile/shared/models/asset.dart'; -import 'package:immich_mobile/extensions/collection_extensions.dart'; import 'package:scrollable_positioned_list/scrollable_positioned_list.dart'; + import 'asset_grid_data_structure.dart'; -import 'group_divider_title.dart'; import 'disable_multi_select_button.dart'; import 'draggable_scrollbar_custom.dart'; +import 'group_divider_title.dart'; typedef ImmichAssetGridSelectionListener = void Function( bool, @@ -72,6 +75,9 @@ class ImmichAssetGridViewState extends State { final ItemPositionsListener _itemPositionsListener = ItemPositionsListener.create(); + /// The timestamp when the haptic feedback was last invoked + int _hapticFeedbackTS = 0; + DateTime? _prevItemTime; bool _scrolling = false; final Set _selectedAssets = LinkedHashSet(equals: (a, b) => a.id == b.id, hashCode: (a) => a.id); @@ -399,6 +405,8 @@ class ImmichAssetGridViewState extends State { if (widget.preselectedAssets != null) { _selectedAssets.addAll(widget.preselectedAssets!); } + + _itemPositionsListener.itemPositions.addListener(_hapticsListener); } @override @@ -415,6 +423,41 @@ class ImmichAssetGridViewState extends State { widget.visibleItemsListener?.call(values); } + void _hapticsListener() { + /// throttle interval for the haptic feedback in microseconds. + /// Currently set to 100ms. + const feedbackInterval = 100000; + + final values = _itemPositionsListener.itemPositions.value; + final start = values.firstOrNull; + + if (start != null) { + final pos = start.index; + final maxLength = widget.renderList.elements.length; + if (pos < 0 || pos >= maxLength) { + return; + } + + final date = widget.renderList.elements[pos].date; + + // only provide the feedback if the prev. date is known. + // Otherwise the app would provide the haptic feedback + // on startup. + if (_prevItemTime == null) { + _prevItemTime = date; + } else if (_prevItemTime?.year != date.year || + _prevItemTime?.month != date.month) { + _prevItemTime = date; + + final now = Timeline.now; + if (now > (_hapticFeedbackTS + feedbackInterval)) { + _hapticFeedbackTS = now; + HapticFeedback.heavyImpact(); + } + } + } + } + void _scrollToTop() { // for some reason, this is necessary as well in order // to correctly reposition the drag thumb scroll bar From 1d938899205cc3421836ffd83827823c48accf19 Mon Sep 17 00:00:00 2001 From: shenlong <139912620+shenlong-tanwen@users.noreply.github.com> Date: Mon, 5 Feb 2024 03:07:08 +0000 Subject: [PATCH 009/104] fix(mobile): debounce map layer update (#6861) Co-authored-by: shenlong-tanwen <139912620+shalong-tanwen@users.noreply.github.com> --- .../lib/extensions/maplibrecontroller_extensions.dart | 11 +++++++++++ mobile/lib/modules/map/views/map_page.dart | 5 ++++- 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/mobile/lib/extensions/maplibrecontroller_extensions.dart b/mobile/lib/extensions/maplibrecontroller_extensions.dart index 0c1e62e308..e01655b3a8 100644 --- a/mobile/lib/extensions/maplibrecontroller_extensions.dart +++ b/mobile/lib/extensions/maplibrecontroller_extensions.dart @@ -1,3 +1,4 @@ +import 'dart:async'; import 'dart:math'; import 'package:flutter/services.dart'; @@ -6,6 +7,8 @@ import 'package:immich_mobile/modules/map/utils/map_utils.dart'; import 'package:maplibre_gl/maplibre_gl.dart'; extension MapMarkers on MaplibreMapController { + static var _completer = Completer()..complete(); + Future addGeoJSONSourceForMarkers(List markers) async { return addSource( MapUtils.defaultSourceId, @@ -16,6 +19,12 @@ extension MapMarkers on MaplibreMapController { } Future reloadAllLayersForMarkers(List markers) async { + // Wait for previous reload to complete + if (!_completer.isCompleted) { + return _completer.future; + } + _completer = Completer(); + // !! Make sure to remove layers before sources else the native // maplibre library would crash when removing the source saying that // the source is still in use @@ -36,6 +45,8 @@ extension MapMarkers on MaplibreMapController { MapUtils.defaultHeatMapLayerId, MapUtils.defaultHeatMapLayerProperties, ); + + _completer.complete(); } Future addMarkerAtLatLng(LatLng centre) async { diff --git a/mobile/lib/modules/map/views/map_page.dart b/mobile/lib/modules/map/views/map_page.dart index 1882e32616..671e501bcc 100644 --- a/mobile/lib/modules/map/views/map_page.dart +++ b/mobile/lib/modules/map/views/map_page.dart @@ -41,6 +41,7 @@ class MapPage extends HookConsumerWidget { final bottomSheetStreamController = useStreamController(); final selectedMarker = useValueNotifier<_AssetMarkerMeta?>(null); final assetsDebouncer = useDebouncer(); + final layerDebouncer = useDebouncer(interval: const Duration(seconds: 1)); final isLoading = useProcessingOverlay(); final scrollController = useScrollController(); final markerDebouncer = @@ -77,7 +78,9 @@ class MapPage extends HookConsumerWidget { // removes all sources and layers and re-adds them with the updated markers Future reloadLayers() async { if (mapController.value != null) { - mapController.value!.reloadAllLayersForMarkers(markers.value); + layerDebouncer.run( + () => mapController.value!.reloadAllLayersForMarkers(markers.value), + ); } } From 8e4bf3042486caa72847fd8538776b6bc8fde8ed Mon Sep 17 00:00:00 2001 From: bo0tzz Date: Mon, 5 Feb 2024 04:30:29 +0100 Subject: [PATCH 010/104] chore(docs): Small FAQ tweaks and nits (#6880) * chore(docs): Small FAQ tweaks and nits * chore: format:fix --- docs/docs/FAQ.mdx | 74 +++++++++++++++++++++++++---------------------- 1 file changed, 40 insertions(+), 34 deletions(-) diff --git a/docs/docs/FAQ.mdx b/docs/docs/FAQ.mdx index 72aaee72d4..1465cc9fd5 100644 --- a/docs/docs/FAQ.mdx +++ b/docs/docs/FAQ.mdx @@ -16,18 +16,18 @@ You can see the list of all users by running [list-users](/docs/administration/s ### What is the difference between the cloud icons on the mobile app? -| Icon | Description | -| ---------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------- | -| ![cloud](/img/cloud.svg) | Asset is only available in the cloud and was uploaded from some other device (like the web client) or was deleted from this device after upload | -| ![cloud-cross](/img/cloud-off.svg) | Asset is only available locally and has not yet been backed up | -| ![cloud-done](/img/cloud-done.svg) | Asset was uploaded from this device and is now backed up to the server; the original file is still on the device | +| Icon | Description | +| ---------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------ | +| ![cloud](/img/cloud.svg) | Asset is only available on the server and was uploaded from some other device (like the web client) or was deleted from this device after upload | +| ![cloud-cross](/img/cloud-off.svg) | Asset is only available locally and has not yet been backed up | +| ![cloud-done](/img/cloud-done.svg) | Asset was uploaded from this device and is now backed up to the server; the original file is still on the device | ### I cannot log into the application after an update. What can I do? First, verify that the mobile app and server are both running the same version (major and minor). :::note -App store updates sometimes take longer because the stores (play store; Google and app store; Apple) +App store updates sometimes take longer because the stores (Google play store and Apple app store) need to approve the update first which may take some time. ::: @@ -54,7 +54,7 @@ This often happens when using a reverse proxy (such as nginx or Cloudflare tunne ### Why are some photos stored in the file system with the wrong date? -There are a few different scenarios that can lead to this situation. The solution is to simply run the storage migration job again. The job is only _automatically_ run once per asset, after upload. If metadata extraction originally failed, the jobs were cleared/cancelled, etc. the job may not have run automatically the first time. +There are a few different scenarios that can lead to this situation. The solution is to run the storage migration job again. The job is only _automatically_ run once per asset, after upload. If metadata extraction originally failed, the jobs were cleared/cancelled, etc. the job may not have run automatically the first time. ### How can I hide photos from the timeline? @@ -66,11 +66,11 @@ See [Backup and Restore](/docs/administration/backup-and-restore.md). ### Does Immich support reading existing face tag metadata? -No, it currently does not. +No, it currently does not. There is an [open feature request on GitHub](https://github.com/immich-app/immich/discussions/4348). ### Does Immich support filtering of NSFW images? -No, it currently does not, but there is an [open discussion about it On Github](https://github.com/immich-app/immich/discussions/2451). You can submit a pull request or vote for the discussion. +No, it currently does not. There is an [open feature request on Github](https://github.com/immich-app/immich/discussions/2451). ### Why are there so many thumbnail generation jobs? @@ -90,9 +90,13 @@ There are no requirements for assets to be unique across users. If multiple user Immich uses a player with known HDR color display issues. We are experimenting with a different player that provides better color profiles for HDR content for future improvements. +### Why does Immich transcode my videos to a lower quality? + +Immich always keeps your original files. Alongside that, it generates a transcoded version for compatibility and performance reasons. + ### How can I delete transcoded videos without deleting the original? -The transcode of an asset can be deleted by setting a transcode policy that makes it unnecessary, then running a transcoding job for that asset. This can be done on a per-asset basis by starting a transcoding job for an asset (with the _Refresh encoded videos_ button in the asset viewer options. Or, for all assets by running transcoding jobs for all assets. +The transcoded version of an asset can be deleted by setting a transcode policy that makes it unnecessary, then running a transcoding job for that asset. This can be done on a per-asset basis by starting a transcoding job for a single asset with the _Refresh encoded videos_ button in the asset viewer options, or for all assets by running transcoding jobs for all assets from the administration page. To update the transcode policy, navigate to Administration > Video Transcoding Settings > Transcoding Policy and select a policy from the drop-down. This policy will determine whether an existing transcode will be deleted or overwritten in the transcoding job. If a video should be transcoded according to this policy, an existing transcode is overwritten. If not, then it is deleted. @@ -143,19 +147,19 @@ UPDATE assets SET "ownerId" = '' WHERE "ownerId" = '' ### Can I keep my existing album structure while importing assets into Immich? -Yes. You can by use [Immich CLI](/docs/features/command-line-interface) along with the `--album` flag. +Yes, by using the [Immich CLI](/docs/features/command-line-interface) along with the `--album` flag. ### Is there a way to reorder photos within an album? -No, not yet. For updates on this planned feature, follow the [GitHub discussion](https://github.com/immich-app/immich/discussions/1689), +No, not yet. For updates on this planned feature, follow the [GitHub discussion](https://github.com/immich-app/immich/discussions/1689). --- ## External Library -### Can I add an external library while keeping the existing albums structure? +### Can I add an external library while keeping the existing album structure? -We haven't put in an official mechanism to create albums from external libraries at the moment., but there are some [workarounds from the community](https://github.com/immich-app/immich/discussions/4279) which you can find here to help you achieve that. +We haven't put in an official mechanism to create albums from external libraries at the moment, but there are some [workarounds from the community](https://github.com/immich-app/immich/discussions/4279) to help you achieve that. ### What happens to duplicates in external libraries? @@ -185,7 +189,7 @@ However, disabling all jobs will not disable the machine learning service itself ### I'm getting errors about models being corrupt or failing to download. What do I do? -You can delete the model cache volume, which is where models are downloaded to. This will give the service a clean environment to download the model again. +You can delete the model cache volume, which is where models are downloaded to. This will give the service a clean environment to download the model again. If models are failing to download entirely, you can manually download them from [Huggingface](https://huggingface.co/immich-app) and place them in the cache folder. ### Why did Immich decide to remove object detection? @@ -194,7 +198,7 @@ For more info see [here](https://github.com/immich-app/immich/pull/5903) ### Can I use a custom CLIP model? -No, this is not supported. Only models listed in the [Huggingface](https://huggingface.co/immich-app) are compatible. Feel free to make a feature request if there's a model not listed here that you think should be added. +No, this is not supported. Only models listed in the [Huggingface](https://huggingface.co/immich-app) page are compatible. Feel free to make a feature request if there's a model not listed here that you think should be added. ### I want to be able to search in other languages besides English. How can I do that? @@ -206,9 +210,8 @@ Feel free to make a feature request if there's a model you want to use that isn' ### Does Immich support Facial Recognition for videos ? -This is not currently implemented, but may be in the future. - -On the other hand, Immich does scan video thumbnails for faces, so it can perform recognition if the face is clear in the video thumbnail. +Immich's machine learning feature operate on the generated thumbnail. If a face is visible in the video's thumbnail it will be picked up by facial recognition. +Scanning the entire video for faces may be implemented in the future. ### Does Immich have animal recognition? @@ -216,7 +219,7 @@ No. ### I'm getting a lot of "faces" that aren't faces, what can I do? -You can increase the MIN DETECTION SCORE to 0.8 to help prevent bad thumbnails. However, a score of 0.9 might filter out too many real faces depending on the library used. If you just want to hide specific faces, you can adjust the 'MIN FACES DETECTED' setting in the administration panel +You can increase the MIN DETECTION SCORE to 0.8 to help prevent bad thumbnails. Setting the score too high (above 0.9) might filter out too many real faces depending on the library used. If you just want to hide specific faces, you can adjust the 'MIN FACES DETECTED' setting in the administration panel to increase the bar for what the algorithm considers a "core face" for that person, reducing the chance of bad thumbnails being chosen. ### The immich_model-cache volume takes up a lot of space, what could be the problem? @@ -236,7 +239,7 @@ To do this you can run: ### Why is Immich slow on low-memory systems like the Raspberry Pi? -Immich optionally uses machine learning for several features. However, it can be too heavy to run on a Raspberry Pi. You can [mitigate](/docs/FAQ#can-i-lower-cpu-and-ram-usage) this or transfer to host Immich's machine-learning container on a [more powerful system](/docs/guides/remote-machine-learning) ,or [disable](/docs/FAQ#how-can-i-disable-machine-learning) machine learning entirely. +Immich optionally uses machine learning for several features. However, it can be too heavy to run on a Raspberry Pi. You can [mitigate](/docs/FAQ#can-i-lower-cpu-and-ram-usage) this or host Immich's machine-learning container on a [more powerful system](/docs/guides/remote-machine-learning), or [disable](/docs/FAQ#how-can-i-disable-machine-learning) machine learning entirely. ### Can I lower CPU and RAM usage? @@ -251,9 +254,9 @@ The initial backup is the most intensive due to the number of jobs running. The ### Can I limit the amount of CPU and RAM usage? By default, a container has no resource constraints and can use as much of a given resource as the host's kernel scheduler allows. -You can look at the [original docker docs](https://docs.docker.com/config/containers/resource_constraints/) or use this [guide](https://www.baeldung.com/ops/docker-memory-limit) to learn how to do this. +You can look at the [original docker docs](https://docs.docker.com/config/containers/resource_constraints/) or use this [guide](https://www.baeldung.com/ops/docker-memory-limit) to learn how to limit this. -### How an I boost machine learning speed? +### How can I boost machine learning speed? :::note This advice improves throughput, not latency. This is to say that it will make Smart Search jobs process more quickly, but it won't make searching faster. @@ -262,17 +265,17 @@ This advice improves throughput, not latency. This is to say that it will make S You can increase throughput by increasing the job concurrency for machine learning jobs (Smart Search, Face Detection). With higher concurrency, the host will work on more assets in parallel. You can do this by navigating to Administration > Settings > Job Settings and increasing concurrency as needed. :::danger -On a normal machine, 2 or 3 concurrent jobs can probably max the CPU, so if you're not hitting those maximums with, say, 30 jobs. -Note that storage speed and latency may quickly become the limiting factor; particularly when using HDDs. +On a normal machine, 2 or 3 concurrent jobs can probably max the CPU. Beyond this, note that storage speed and latency may quickly become the limiting factor; particularly when using HDDs. Do not exaggerate with the amount of jobs because you're probably thoroughly overloading the server. -more info [here](https://discord.com/channels/979116623879368755/994044917355663450/1174711719994605708) +More detail can be found [here](https://discord.com/channels/979116623879368755/994044917355663450/1174711719994605708) ::: ### Why is Immich using so much of my CPU? -When a large amount of assets are uploaded to Immich it makes sense that the CPU and RAM will be heavily used due to machine learning work and creating image thumbnails after that, the percentage of CPU usage will drop to around 3-5% usage +When a large amount of assets are uploaded to Immich it makes sense that the CPU and RAM will be heavily used due to machine learning work and creating image thumbnails. +Once this process completes, the percentage of CPU usage will drop to around 3-5% usage --- @@ -280,13 +283,12 @@ When a large amount of assets are uploaded to Immich it makes sense that the CPU ### How can I see Immich logs? -Most Immich components are typically deployed using docker. To see logs for deployed docker containers, you can use the [Docker CLI](https://docs.docker.com/engine/reference/commandline/cli/), specifically the `docker logs` command. For examples, see [Docker Help](/docs/guides/docker-help.md). +Immich components are typically deployed using docker. To see logs for deployed docker containers, you can use the [Docker CLI](https://docs.docker.com/engine/reference/commandline/cli/), specifically the `docker logs` command. For examples, see [Docker Help](/docs/guides/docker-help.md). ### How can I run Immich as a non-root user? -1. Set the `PUID`/`PGID` environment variables (in `.env`). -2. Set the corresponding `user` argument in `docker-compose` for each service. -3. Add an additional volume to `immich-microservices` that mounts internally to `/usr/src/app/.reverse-geocoding-dump`. +You can change the user in the container by setting the `user` argument in `docker-compose.yml` for each service. +You may need to add an additional volume to `immich-microservices` that mounts internally to `/usr/src/app/.reverse-geocoding-dump`. The non-root user/group needs read/write access to the volume mounts, including `UPLOAD_LOCATION`. @@ -299,6 +301,10 @@ Data for Immich comes in two forms: To remove the **Metadata** you can stop Immich and delete the volume. +:::warning +This will destroy your database and reset your instance, meaning that you start from scratch. +::: + ```bash title="Remove Immich (containers and volumes)" docker compose down -v ``` @@ -308,7 +314,7 @@ If you use portainer, bring down the stack in portainer. Go into the volumes sec and remove all the volumes related to immcih then restart the stack. ::: -After removing the containers and volumes, the **Files** can be cleaned up (if necessary) from the `UPLOAD_LOCATION` by simply deleting any unwanted files or folders. +After removing the containers and volumes, the **Files** should be removed from the `UPLOAD_LOCATION` to provide a clean start. ### Why does the machine learning service report workers crashing? @@ -324,6 +330,6 @@ If it mentions SIGILL (note the lack of a K) or error code 132, it most likely m If your version of Immich is below 1.92.0 and the crash occurs after logs about tracing or exporting a model, consider either upgrading or disabling the Tag Objects job. -### Why do I get the error "duplicate key value violates unique constraint" in the log files? +### Why does Immich log migration errors on startup? -Because of Immich's container structure, this error can be seen when both immich and immich-microservices start at the same time and attempt to migrate or create the database structure. Since the database migration is run sequentially and inside of transactions, this error message does not cause harm to your installation of Immich and can safely be ignored. If needed, you can manually restart Immich by running `docker restart immich immich-microservices`. +Sometimes Immich logs errors such as "duplicate key value violates unique constraint" or "column (...) of relation (...) already exists". Because of Immich's container structure, this error can be seen when both immich and immich-microservices start at the same time and attempt to migrate or create the database structure. Since the database migration is run sequentially and inside of transactions, this error message does not cause harm to your installation of Immich and can safely be ignored. If needed, you can manually restart Immich by running `docker restart immich immich-microservices`. From f6b4024a217a54e921880e7de08e3d186691cb9e Mon Sep 17 00:00:00 2001 From: martyfuhry Date: Mon, 5 Feb 2024 10:11:30 -0500 Subject: [PATCH 011/104] feat(mobile): Adds show password field to login (#6918) Adds show password field to login --- mobile/lib/modules/login/ui/login_form.dart | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/mobile/lib/modules/login/ui/login_form.dart b/mobile/lib/modules/login/ui/login_form.dart index 79873ef6e8..4c8a12bb2f 100644 --- a/mobile/lib/modules/login/ui/login_form.dart +++ b/mobile/lib/modules/login/ui/login_form.dart @@ -515,7 +515,7 @@ class EmailInput extends StatelessWidget { } } -class PasswordInput extends StatelessWidget { +class PasswordInput extends HookConsumerWidget { final TextEditingController controller; final FocusNode? focusNode; final Function()? onSubmit; @@ -528,9 +528,11 @@ class PasswordInput extends StatelessWidget { }); @override - Widget build(BuildContext context) { + Widget build(BuildContext context, WidgetRef ref) { + final isPasswordVisible = useState(false); + return TextFormField( - obscureText: true, + obscureText: !isPasswordVisible.value, controller: controller, decoration: InputDecoration( labelText: 'login_form_label_password'.tr(), @@ -540,6 +542,14 @@ class PasswordInput extends StatelessWidget { fontWeight: FontWeight.normal, fontSize: 14, ), + suffixIcon: IconButton( + onPressed: () => isPasswordVisible.value = !isPasswordVisible.value, + icon: Icon( + isPasswordVisible.value + ? Icons.visibility_off_sharp + : Icons.visibility_sharp, + ), + ), ), autofillHints: const [AutofillHints.password], keyboardType: TextInputType.text, From c29976cd6f28970afd839f4794fa39caf668079a Mon Sep 17 00:00:00 2001 From: martyfuhry Date: Mon, 5 Feb 2024 14:12:33 -0500 Subject: [PATCH 012/104] feat(mobile): Memories activity is now full screen, better image fit, adds progress indicator (#6793) * Made memories full screen * Uses linear bar and fits the card better for memories * Fixes pageview close button moving with pages * Uses hooks instead of stateful components * Adds ticks to the progress indicator * Rounds the edges of the progress bar * Fixes trailing comma analyze error * Adds padding and hero to memories * Fixes an issue with initial index set and adds hero / proper padding * Fixes aspect ratio calculation * Color --------- Co-authored-by: Alex --- .../lib/modules/memories/ui/memory_card.dart | 60 +++--- .../modules/memories/ui/memory_epilogue.dart | 136 ++++++------ .../lib/modules/memories/ui/memory_lane.dart | 87 ++++---- .../ui/memory_progress_indicator.dart | 58 ++++++ .../modules/memories/views/memory_page.dart | 194 ++++++++++++------ 5 files changed, 337 insertions(+), 198 deletions(-) create mode 100644 mobile/lib/modules/memories/ui/memory_progress_indicator.dart diff --git a/mobile/lib/modules/memories/ui/memory_card.dart b/mobile/lib/modules/memories/ui/memory_card.dart index 883c5b3866..f9231338c5 100644 --- a/mobile/lib/modules/memories/ui/memory_card.dart +++ b/mobile/lib/modules/memories/ui/memory_card.dart @@ -12,18 +12,14 @@ import 'package:openapi/api.dart'; class MemoryCard extends StatelessWidget { final Asset asset; final void Function() onTap; - final void Function() onClose; final String title; - final String? rightCornerText; final bool showTitle; const MemoryCard({ required this.asset, required this.onTap, - required this.onClose, required this.title, required this.showTitle, - this.rightCornerText, super.key, }); @@ -65,34 +61,34 @@ class MemoryCard extends StatelessWidget { ), GestureDetector( onTap: onTap, - child: ImmichImage( - asset, - fit: BoxFit.fitWidth, - height: double.infinity, - width: double.infinity, - type: ThumbnailFormat.JPEG, - preferredLocalAssetSize: 2048, - ), - ), - Positioned( - top: 2.0, - left: 2.0, - child: IconButton( - onPressed: onClose, - icon: const Icon(Icons.close_rounded), - color: Colors.grey[400], - ), - ), - Positioned( - right: 18.0, - top: 18.0, - child: Text( - rightCornerText ?? "", - style: TextStyle( - color: Colors.grey[200], - fontSize: 12.0, - fontWeight: FontWeight.bold, - ), + child: LayoutBuilder( + builder: (context, constraints) { + // Determine the fit using the aspect ratio + BoxFit fit = BoxFit.fitWidth; + if (asset.width != null && asset.height != null) { + final aspectRatio = asset.width! / asset.height!; + final phoneAspectRatio = + constraints.maxWidth / constraints.maxHeight; + // Look for a 25% difference in either direction + if (phoneAspectRatio * .75 < aspectRatio && + phoneAspectRatio * 1.25 > aspectRatio) { + // Cover to look nice if we have nearly the same aspect ratio + fit = BoxFit.cover; + } + } + + return Hero( + tag: 'memory-${asset.id}', + child: ImmichImage( + asset, + fit: fit, + height: double.infinity, + width: double.infinity, + type: ThumbnailFormat.JPEG, + preferredLocalAssetSize: 2048, + ), + ); + }, ), ), if (showTitle) diff --git a/mobile/lib/modules/memories/ui/memory_epilogue.dart b/mobile/lib/modules/memories/ui/memory_epilogue.dart index 4e32ae6ac5..8dd28637df 100644 --- a/mobile/lib/modules/memories/ui/memory_epilogue.dart +++ b/mobile/lib/modules/memories/ui/memory_epilogue.dart @@ -16,7 +16,7 @@ class _MemoryEpilogueState extends State late final _animationController = AnimationController( vsync: this, duration: const Duration( - seconds: 3, + seconds: 2, ), )..repeat( reverse: true, @@ -29,7 +29,7 @@ class _MemoryEpilogueState extends State super.initState(); _animation = CurvedAnimation( parent: _animationController, - curve: Curves.easeInOut, + curve: Curves.easeIn, ); } @@ -41,74 +41,82 @@ class _MemoryEpilogueState extends State @override Widget build(BuildContext context) { - return Column( - crossAxisAlignment: CrossAxisAlignment.center, - mainAxisAlignment: MainAxisAlignment.center, - children: [ - Expanded( - child: Column( - mainAxisAlignment: MainAxisAlignment.center, - children: [ - const Icon( - Icons.check_circle_outline_sharp, - color: immichDarkThemePrimaryColor, - size: 64.0, - ), - const SizedBox(height: 16.0), - Text( - 'All caught up', - style: Theme.of(context).textTheme.headlineMedium?.copyWith( - color: Colors.white, + return SafeArea( + child: Stack( + children: [ + Positioned.fill( + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + const Icon( + Icons.check_circle_outline_sharp, + color: immichDarkThemePrimaryColor, + size: 64.0, + ), + const SizedBox(height: 16.0), + Text( + 'All caught up', + style: Theme.of(context).textTheme.headlineMedium?.copyWith( + color: Colors.white, + ), + ), + const SizedBox(height: 16.0), + Text( + 'Check back tomorrow for more memories', + style: Theme.of(context).textTheme.bodyMedium?.copyWith( + color: Colors.white, + ), + ), + const SizedBox(height: 16.0), + TextButton( + onPressed: widget.onStartOver, + child: Text( + 'Start Over', + style: context.textTheme.displayMedium?.copyWith( + color: immichDarkThemePrimaryColor, ), - ), - const SizedBox(height: 16.0), - Text( - 'Check back tomorrow for more memories', - style: Theme.of(context).textTheme.bodyMedium?.copyWith( - color: Colors.white, - ), - ), - const SizedBox(height: 16.0), - TextButton( - onPressed: widget.onStartOver, - child: Text( - 'Start Over', - style: context.textTheme.displayMedium?.copyWith( - color: immichDarkThemePrimaryColor, ), ), - ), - ], + ], + ), ), - ), - Column( - children: [ - SizedBox( - height: 48, - child: AnimatedBuilder( - animation: _animation, - builder: (context, child) { - return Transform.translate( - offset: Offset(0, 5 * _animationController.value), - child: child, - ); - }, - child: const Icon( - size: 32, - Icons.expand_less_sharp, - color: Colors.white, - ), + Positioned( + bottom: 0, + left: 0, + right: 0, + child: Padding( + padding: const EdgeInsets.only(bottom: 16.0), + child: Column( + children: [ + SizedBox( + height: 48, + child: AnimatedBuilder( + animation: _animation, + builder: (context, child) { + return Transform.translate( + offset: Offset(0, 8 * _animationController.value), + child: child, + ); + }, + child: const Icon( + size: 32, + Icons.expand_less_sharp, + color: Colors.white, + ), + ), + ), + Text( + 'Swipe up to close', + style: Theme.of(context).textTheme.bodyMedium?.copyWith( + color: Colors.white, + ), + ), + ], ), ), - Text( - 'Swipe up to close', - style: Theme.of(context).textTheme.bodyMedium?.copyWith( - color: Colors.white, - ), - ), - ], - ), - ], + ), + ], + ), ); } } diff --git a/mobile/lib/modules/memories/ui/memory_lane.dart b/mobile/lib/modules/memories/ui/memory_lane.dart index 4e6d4f81a6..1a47d9b661 100644 --- a/mobile/lib/modules/memories/ui/memory_lane.dart +++ b/mobile/lib/modules/memories/ui/memory_lane.dart @@ -16,41 +16,46 @@ class MemoryLane extends HookConsumerWidget { final memoryLane = memoryLaneFutureProvider .whenData( (memories) => memories != null - ? Container( - margin: const EdgeInsets.only(top: 10, left: 10), + ? SizedBox( height: 200, child: ListView.builder( scrollDirection: Axis.horizontal, shrinkWrap: true, itemCount: memories.length, + padding: const EdgeInsets.only( + right: 8.0, + bottom: 8, + top: 10, + left: 10, + ), itemBuilder: (context, index) { final memory = memories[index]; - return Padding( - padding: const EdgeInsets.only(right: 8.0, bottom: 8), - child: GestureDetector( - onTap: () { - HapticFeedback.heavyImpact(); - context.pushRoute( - MemoryRoute( - memories: memories, - memoryIndex: index, + return GestureDetector( + onTap: () { + HapticFeedback.heavyImpact(); + context.pushRoute( + MemoryRoute( + memories: memories, + memoryIndex: index, + ), + ); + }, + child: Stack( + children: [ + Card( + elevation: 3, + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(13.0), ), - ); - }, - child: Stack( - children: [ - Card( - elevation: 3, - shape: RoundedRectangleBorder( - borderRadius: BorderRadius.circular(13.0), + clipBehavior: Clip.hardEdge, + child: ColorFiltered( + colorFilter: ColorFilter.mode( + Colors.black.withOpacity(0.2), + BlendMode.darken, ), - clipBehavior: Clip.hardEdge, - child: ColorFiltered( - colorFilter: ColorFilter.mode( - Colors.black.withOpacity(0.2), - BlendMode.darken, - ), + child: Hero( + tag: 'memory-${memory.assets[0].id}', child: ImmichImage( memory.assets[0], fit: BoxFit.cover, @@ -61,25 +66,25 @@ class MemoryLane extends HookConsumerWidget { ), ), ), - Positioned( - bottom: 16, - left: 16, - child: ConstrainedBox( - constraints: const BoxConstraints( - maxWidth: 114, - ), - child: Text( - memory.title, - style: const TextStyle( - fontWeight: FontWeight.w600, - color: Colors.white, - fontSize: 15, - ), + ), + Positioned( + bottom: 16, + left: 16, + child: ConstrainedBox( + constraints: const BoxConstraints( + maxWidth: 114, + ), + child: Text( + memory.title, + style: const TextStyle( + fontWeight: FontWeight.w600, + color: Colors.white, + fontSize: 15, ), ), ), - ], - ), + ), + ], ), ); }, diff --git a/mobile/lib/modules/memories/ui/memory_progress_indicator.dart b/mobile/lib/modules/memories/ui/memory_progress_indicator.dart new file mode 100644 index 0000000000..697d910a4e --- /dev/null +++ b/mobile/lib/modules/memories/ui/memory_progress_indicator.dart @@ -0,0 +1,58 @@ +import 'package:flutter/material.dart'; +import 'package:immich_mobile/constants/immich_colors.dart'; +import 'package:immich_mobile/extensions/build_context_extensions.dart'; + +class MemoryProgressIndicator extends StatelessWidget { + /// The number of ticks in the progress indicator + final int ticks; + + /// The current value of the indicator + final double value; + + const MemoryProgressIndicator({ + super.key, + required this.ticks, + required this.value, + }); + + @override + Widget build(BuildContext context) { + return LayoutBuilder( + builder: (context, constraints) { + final tickWidth = constraints.maxWidth / ticks; + return ClipRRect( + borderRadius: const BorderRadius.all(Radius.circular(2.0)), + child: Stack( + children: [ + LinearProgressIndicator( + value: value, + backgroundColor: Colors.grey[600], + color: immichDarkThemePrimaryColor, + ), + Row( + mainAxisAlignment: MainAxisAlignment.spaceEvenly, + children: List.generate( + ticks, + (i) => Container( + width: tickWidth, + height: 4, + decoration: BoxDecoration( + border: i == 0 + ? null + : Border( + left: BorderSide( + color: context.colorScheme.onSecondaryContainer, + width: 1, + ), + ), + ), + ), + ), + ), + ], + ), + ); + }, + ); + } +} diff --git a/mobile/lib/modules/memories/views/memory_page.dart b/mobile/lib/modules/memories/views/memory_page.dart index fbc04feae5..26104054c3 100644 --- a/mobile/lib/modules/memories/views/memory_page.dart +++ b/mobile/lib/modules/memories/views/memory_page.dart @@ -7,6 +7,7 @@ import 'package:immich_mobile/modules/memories/models/memory.dart'; import 'package:immich_mobile/modules/memories/ui/memory_bottom_info.dart'; import 'package:immich_mobile/modules/memories/ui/memory_card.dart'; import 'package:immich_mobile/modules/memories/ui/memory_epilogue.dart'; +import 'package:immich_mobile/modules/memories/ui/memory_progress_indicator.dart'; import 'package:immich_mobile/shared/models/asset.dart'; import 'package:immich_mobile/shared/ui/immich_image.dart'; import 'package:openapi/api.dart' as api; @@ -24,15 +25,28 @@ class MemoryPage extends HookConsumerWidget { @override Widget build(BuildContext context, WidgetRef ref) { - final memoryPageController = usePageController(initialPage: memoryIndex); - final memoryAssetPageController = usePageController(); final currentMemory = useState(memories[memoryIndex]); final currentAssetPage = useState(0); + final currentMemoryIndex = useState(memoryIndex); final assetProgress = useState( "${currentAssetPage.value + 1}|${currentMemory.value.assets.length}", ); const bgColor = Colors.black; + /// The list of all of the asset page controllers + final memoryAssetPageControllers = + List.generate(memories.length, (i) => usePageController()); + + /// The main vertically scrolling page controller with each list of memories + final memoryPageController = usePageController(initialPage: memoryIndex); + + // The Page Controller that scrolls horizontally with all of the assets + useEffect(() { + // Memories is an immersive activity + SystemChrome.setEnabledSystemUIMode(SystemUiMode.immersive); + return null; + }); + toNextMemory() { memoryPageController.nextPage( duration: const Duration(milliseconds: 500), @@ -43,7 +57,10 @@ class MemoryPage extends HookConsumerWidget { toNextAsset(int currentAssetIndex) { if (currentAssetIndex + 1 < currentMemory.value.assets.length) { // Go to the next asset - memoryAssetPageController.nextPage( + PageController controller = + memoryAssetPageControllers[currentMemoryIndex.value]; + + controller.nextPage( curve: Curves.easeInOut, duration: const Duration(milliseconds: 500), ); @@ -154,67 +171,122 @@ class MemoryPage extends HookConsumerWidget { }, child: Scaffold( backgroundColor: bgColor, - body: SafeArea( - child: PageView.builder( - physics: const BouncingScrollPhysics( - parent: AlwaysScrollableScrollPhysics(), - ), - scrollDirection: Axis.vertical, - controller: memoryPageController, - onPageChanged: (pageNumber) { - HapticFeedback.mediumImpact(); - if (pageNumber < memories.length) { - currentMemory.value = memories[pageNumber]; - } + body: PopScope( + onPopInvoked: (didPop) { + // Remove immersive mode and go back to normal mode + SystemChrome.setEnabledSystemUIMode(SystemUiMode.edgeToEdge); + }, + child: SafeArea( + child: PageView.builder( + physics: const BouncingScrollPhysics( + parent: AlwaysScrollableScrollPhysics(), + ), + scrollDirection: Axis.vertical, + controller: memoryPageController, + onPageChanged: (pageNumber) { + HapticFeedback.mediumImpact(); + if (pageNumber < memories.length) { + currentMemoryIndex.value = pageNumber; + currentMemory.value = memories[pageNumber]; + } - currentAssetPage.value = 0; + currentAssetPage.value = 0; - updateProgressText(); - }, - itemCount: memories.length + 1, - itemBuilder: (context, mIndex) { - // Build last page - if (mIndex == memories.length) { - return MemoryEpilogue( - onStartOver: () => memoryPageController.animateToPage( - 0, - duration: const Duration(seconds: 1), - curve: Curves.easeInOut, - ), - ); - } - // Build horizontal page - return Column( - children: [ - Expanded( - child: PageView.builder( - physics: const BouncingScrollPhysics( - parent: AlwaysScrollableScrollPhysics(), - ), - controller: memoryAssetPageController, - onPageChanged: onAssetChanged, - scrollDirection: Axis.horizontal, - itemCount: memories[mIndex].assets.length, - itemBuilder: (context, index) { - final asset = memories[mIndex].assets[index]; - return Container( - color: Colors.black, - child: MemoryCard( - asset: asset, - onTap: () => toNextAsset(index), - onClose: () => context.popRoute(), - rightCornerText: assetProgress.value, - title: memories[mIndex].title, - showTitle: index == 0, - ), - ); - }, + updateProgressText(); + }, + itemCount: memories.length + 1, + itemBuilder: (context, mIndex) { + // Build last page + if (mIndex == memories.length) { + return MemoryEpilogue( + onStartOver: () => memoryPageController.animateToPage( + 0, + duration: const Duration(seconds: 1), + curve: Curves.easeInOut, ), - ), - MemoryBottomInfo(memory: memories[mIndex]), - ], - ); - }, + ); + } + // Build horizontal page + final assetController = memoryAssetPageControllers[mIndex]; + return Column( + children: [ + Padding( + padding: const EdgeInsets.only( + left: 24.0, + right: 24.0, + top: 8.0, + bottom: 2.0, + ), + child: AnimatedBuilder( + animation: assetController, + builder: (context, child) { + double value = 0.0; + if (assetController.hasClients) { + // We can only access [page] if this has clients + value = assetController.page ?? 0; + } + return MemoryProgressIndicator( + ticks: memories[mIndex].assets.length, + value: (value + 1) / memories[mIndex].assets.length, + ); + }, + ), + ), + Expanded( + child: Stack( + children: [ + PageView.builder( + physics: const BouncingScrollPhysics( + parent: AlwaysScrollableScrollPhysics(), + ), + controller: assetController, + onPageChanged: onAssetChanged, + scrollDirection: Axis.horizontal, + itemCount: memories[mIndex].assets.length, + itemBuilder: (context, index) { + final asset = memories[mIndex].assets[index]; + return Container( + color: Colors.black, + child: MemoryCard( + asset: asset, + onTap: () => toNextAsset(index), + title: memories[mIndex].title, + showTitle: index == 0, + ), + ); + }, + ), + Positioned( + top: 8, + left: 8, + child: MaterialButton( + minWidth: 0, + onPressed: () { + // auto_route doesn't invoke pop scope, so + // turn off full screen mode here + // https://github.com/Milad-Akarie/auto_route_library/issues/1799 + context.popRoute(); + SystemChrome.setEnabledSystemUIMode( + SystemUiMode.edgeToEdge, + ); + }, + shape: const CircleBorder(), + color: Colors.white.withOpacity(0.2), + elevation: 0, + child: const Icon( + Icons.close_rounded, + color: Colors.white, + ), + ), + ), + ], + ), + ), + MemoryBottomInfo(memory: memories[mIndex]), + ], + ); + }, + ), ), ), ), From 6ed33da2a48aa618cac737d116688941eb1028ca Mon Sep 17 00:00:00 2001 From: Ben McCann <322311+benmccann@users.noreply.github.com> Date: Mon, 5 Feb 2024 11:29:00 -0800 Subject: [PATCH 013/104] chore: remove axios dependency from CLI (#6888) --- cli/package-lock.json | 182 +- cli/package.json | 1 - cli/src/commands/server-info.command.ts | 6 +- cli/src/commands/upload.command.ts | 39 +- cli/src/services/api.service.ts | 13 +- cli/src/services/session.service.spec.ts | 4 +- cli/src/services/session.service.ts | 4 +- cli/test/cli-test-utils.ts | 4 +- cli/test/e2e/login-key.e2e-spec.ts | 2 +- cli/test/e2e/upload.e2e-spec.ts | 10 +- open-api/bin/generate-open-api.sh | 3 +- .../{client => axios-client}/.gitignore | 0 .../{client => axios-client}/.npmignore | 0 .../.openapi-generator-ignore | 0 .../.openapi-generator/FILES | 1 - .../.openapi-generator/VERSION | 0 .../{client => axios-client}/api.ts | 0 .../{client => axios-client}/base.ts | 0 .../{client => axios-client}/common.ts | 0 .../{client => axios-client}/configuration.ts | 0 .../{client => axios-client}/git_push.sh | 0 .../{client => axios-client}/index.ts | 0 open-api/typescript-sdk/axios.ts | 4 + .../fetch-client/.openapi-generator-ignore | 23 + .../fetch-client/.openapi-generator/FILES | 182 ++ .../fetch-client/.openapi-generator/VERSION | 1 + .../fetch-client/apis/APIKeyApi.ts | 261 +++ .../fetch-client/apis/ActivityApi.ts | 253 +++ .../fetch-client/apis/AlbumApi.ts | 538 +++++ .../fetch-client/apis/AssetApi.ts | 1963 +++++++++++++++++ .../fetch-client/apis/AuditApi.ts | 236 ++ .../fetch-client/apis/AuthenticationApi.ts | 354 +++ .../fetch-client/apis/DownloadApi.ts | 189 ++ .../fetch-client/apis/FaceApi.ts | 136 ++ .../fetch-client/apis/JobApi.ts | 127 ++ .../fetch-client/apis/LibraryApi.ts | 402 ++++ .../fetch-client/apis/OAuthApi.ts | 260 +++ .../fetch-client/apis/PartnerApi.ts | 229 ++ .../fetch-client/apis/PersonApi.ts | 513 +++++ .../fetch-client/apis/SearchApi.ts | 215 ++ .../fetch-client/apis/ServerInfoApi.ts | 302 +++ .../fetch-client/apis/SharedLinkApi.ts | 432 ++++ .../fetch-client/apis/SystemConfigApi.ts | 239 ++ .../fetch-client/apis/TagApi.ts | 415 ++++ .../fetch-client/apis/TrashApi.ts | 146 ++ .../fetch-client/apis/UserApi.ts | 493 +++++ .../typescript-sdk/fetch-client/apis/index.ts | 22 + open-api/typescript-sdk/fetch-client/index.ts | 5 + .../fetch-client/models/APIKeyCreateDto.ts | 65 + .../models/APIKeyCreateResponseDto.ts | 82 + .../fetch-client/models/APIKeyResponseDto.ts | 93 + .../fetch-client/models/APIKeyUpdateDto.ts | 66 + .../fetch-client/models/ActivityCreateDto.ts | 98 + .../models/ActivityResponseDto.ts | 128 ++ .../models/ActivityStatisticsResponseDto.ts | 66 + .../fetch-client/models/AddUsersDto.ts | 66 + .../models/AlbumCountResponseDto.ts | 84 + .../fetch-client/models/AlbumResponseDto.ts | 220 ++ .../models/AllJobStatusResponseDto.ts | 172 ++ .../fetch-client/models/AssetBulkDeleteDto.ts | 74 + .../fetch-client/models/AssetBulkUpdateDto.ts | 122 + .../models/AssetBulkUploadCheckDto.ts | 73 + .../models/AssetBulkUploadCheckItem.ts | 75 + .../models/AssetBulkUploadCheckResponseDto.ts | 73 + .../models/AssetBulkUploadCheckResult.ts | 111 + .../models/AssetFaceResponseDto.ts | 136 ++ .../fetch-client/models/AssetFaceUpdateDto.ts | 73 + .../models/AssetFaceUpdateItem.ts | 75 + .../AssetFaceWithoutPersonResponseDto.ts | 120 + .../models/AssetFileUploadResponseDto.ts | 75 + .../fetch-client/models/AssetIdsDto.ts | 66 + .../models/AssetIdsResponseDto.ts | 95 + .../fetch-client/models/AssetJobName.ts | 39 + .../fetch-client/models/AssetJobsDto.ts | 82 + .../fetch-client/models/AssetOrder.ts | 38 + .../fetch-client/models/AssetResponseDto.ts | 374 ++++ .../models/AssetStatsResponseDto.ts | 84 + .../fetch-client/models/AssetTypeEnum.ts | 40 + .../fetch-client/models/AudioCodec.ts | 39 + .../models/AuditDeletesResponseDto.ts | 75 + .../models/AuthDeviceResponseDto.ts | 111 + .../fetch-client/models/BulkIdResponseDto.ts | 96 + .../fetch-client/models/BulkIdsDto.ts | 66 + .../fetch-client/models/CLIPConfig.ts | 104 + .../fetch-client/models/CLIPMode.ts | 38 + .../fetch-client/models/CQMode.ts | 39 + .../fetch-client/models/ChangePasswordDto.ts | 75 + .../models/CheckExistingAssetsDto.ts | 75 + .../models/CheckExistingAssetsResponseDto.ts | 66 + .../fetch-client/models/Colorspace.ts | 38 + .../fetch-client/models/CreateAlbumDto.ts | 90 + .../fetch-client/models/CreateLibraryDto.ts | 113 + .../models/CreateProfileImageResponseDto.ts | 75 + .../fetch-client/models/CreateTagDto.ts | 82 + .../fetch-client/models/CreateUserDto.ts | 116 + .../models/CuratedLocationsResponseDto.ts | 102 + .../models/CuratedObjectsResponseDto.ts | 102 + .../models/DownloadArchiveInfo.ts | 75 + .../fetch-client/models/DownloadInfoDto.ts | 89 + .../models/DownloadResponseDto.ts | 82 + .../fetch-client/models/EntityType.ts | 38 + .../fetch-client/models/ExifResponseDto.ts | 225 ++ .../fetch-client/models/FaceDto.ts | 66 + .../fetch-client/models/FileChecksumDto.ts | 66 + .../models/FileChecksumResponseDto.ts | 75 + .../fetch-client/models/FileReportDto.ts | 82 + .../fetch-client/models/FileReportFixDto.ts | 73 + .../fetch-client/models/FileReportItemDto.ts | 114 + .../fetch-client/models/JobCommand.ts | 41 + .../fetch-client/models/JobCommandDto.ts | 82 + .../fetch-client/models/JobCountsDto.ts | 111 + .../fetch-client/models/JobName.ts | 48 + .../fetch-client/models/JobSettingsDto.ts | 66 + .../fetch-client/models/JobStatusDto.ts | 88 + .../fetch-client/models/LibraryResponseDto.ts | 154 ++ .../models/LibraryStatsResponseDto.ts | 93 + .../fetch-client/models/LibraryType.ts | 38 + .../fetch-client/models/LogLevel.ts | 42 + .../fetch-client/models/LoginCredentialDto.ts | 75 + .../fetch-client/models/LoginResponseDto.ts | 120 + .../fetch-client/models/LogoutResponseDto.ts | 75 + .../models/MapMarkerResponseDto.ts | 84 + .../fetch-client/models/MapTheme.ts | 38 + .../models/MemoryLaneResponseDto.ts | 82 + .../fetch-client/models/MergePersonDto.ts | 66 + .../fetch-client/models/ModelType.ts | 38 + .../models/OAuthAuthorizeResponseDto.ts | 66 + .../fetch-client/models/OAuthCallbackDto.ts | 66 + .../fetch-client/models/OAuthConfigDto.ts | 66 + .../models/OAuthConfigResponseDto.ts | 99 + .../fetch-client/models/PartnerResponseDto.ts | 215 ++ .../fetch-client/models/PathEntityType.ts | 39 + .../fetch-client/models/PathType.ts | 43 + .../fetch-client/models/PeopleResponseDto.ts | 82 + .../fetch-client/models/PeopleUpdateDto.ts | 73 + .../fetch-client/models/PeopleUpdateItem.ts | 99 + .../fetch-client/models/PersonResponseDto.ts | 102 + .../models/PersonStatisticsResponseDto.ts | 66 + .../fetch-client/models/PersonUpdateDto.ts | 90 + .../models/PersonWithFacesResponseDto.ts | 118 + .../fetch-client/models/QueueStatusDto.ts | 75 + .../fetch-client/models/ReactionLevel.ts | 38 + .../fetch-client/models/ReactionType.ts | 38 + .../fetch-client/models/RecognitionConfig.ts | 117 + .../fetch-client/models/ScanLibraryDto.ts | 73 + .../models/SearchAlbumResponseDto.ts | 106 + .../models/SearchAssetResponseDto.ts | 106 + .../fetch-client/models/SearchExploreItem.ts | 82 + .../models/SearchExploreResponseDto.ts | 82 + .../models/SearchFacetCountResponseDto.ts | 75 + .../models/SearchFacetResponseDto.ts | 82 + .../fetch-client/models/SearchResponseDto.ts | 88 + .../fetch-client/models/ServerConfigDto.ts | 111 + .../fetch-client/models/ServerFeaturesDto.ts | 156 ++ .../models/ServerInfoResponseDto.ts | 120 + .../models/ServerMediaTypesResponseDto.ts | 84 + .../fetch-client/models/ServerPingResponse.ts | 65 + .../models/ServerStatsResponseDto.ts | 100 + .../fetch-client/models/ServerThemeDto.ts | 66 + .../models/ServerVersionResponseDto.ts | 84 + .../models/SharedLinkCreateDto.ts | 137 ++ .../fetch-client/models/SharedLinkEditDto.ts | 115 + .../models/SharedLinkResponseDto.ts | 200 ++ .../fetch-client/models/SharedLinkType.ts | 38 + .../fetch-client/models/SignUpDto.ts | 84 + .../models/SmartInfoResponseDto.ts | 73 + .../fetch-client/models/SystemConfigDto.ts | 283 +++ .../models/SystemConfigFFmpegDto.ts | 274 +++ .../fetch-client/models/SystemConfigJobDto.ts | 154 ++ .../models/SystemConfigLibraryDto.ts | 88 + .../models/SystemConfigLibraryScanDto.ts | 75 + .../models/SystemConfigLibraryWatchDto.ts | 84 + .../models/SystemConfigLoggingDto.ts | 82 + .../models/SystemConfigMachineLearningDto.ts | 106 + .../fetch-client/models/SystemConfigMapDto.ts | 84 + .../models/SystemConfigNewVersionCheckDto.ts | 66 + .../models/SystemConfigOAuthDto.ts | 165 ++ .../models/SystemConfigPasswordLoginDto.ts | 66 + .../models/SystemConfigReverseGeocodingDto.ts | 66 + .../models/SystemConfigServerDto.ts | 75 + .../models/SystemConfigStorageTemplateDto.ts | 84 + .../SystemConfigTemplateStorageOptionDto.ts | 129 ++ .../models/SystemConfigThemeDto.ts | 66 + .../models/SystemConfigThumbnailDto.ts | 100 + .../models/SystemConfigTrashDto.ts | 75 + .../fetch-client/models/TagResponseDto.ts | 100 + .../fetch-client/models/TagTypeEnum.ts | 39 + .../fetch-client/models/ThumbnailFormat.ts | 38 + .../models/TimeBucketResponseDto.ts | 75 + .../fetch-client/models/TimeBucketSize.ts | 38 + .../fetch-client/models/ToneMapping.ts | 40 + .../fetch-client/models/TranscodeHWAccel.ts | 41 + .../fetch-client/models/TranscodePolicy.ts | 41 + .../fetch-client/models/UpdateAlbumDto.ts | 89 + .../fetch-client/models/UpdateAssetDto.ts | 105 + .../fetch-client/models/UpdateLibraryDto.ts | 89 + .../fetch-client/models/UpdatePartnerDto.ts | 66 + .../models/UpdateStackParentDto.ts | 75 + .../fetch-client/models/UpdateTagDto.ts | 65 + .../fetch-client/models/UpdateUserDto.ts | 153 ++ .../fetch-client/models/UsageByUserDto.ts | 111 + .../fetch-client/models/UserAvatarColor.ts | 46 + .../fetch-client/models/UserDto.ts | 109 + .../fetch-client/models/UserResponseDto.ts | 207 ++ .../models/ValidateAccessTokenResponseDto.ts | 66 + .../fetch-client/models/VideoCodec.ts | 39 + .../fetch-client/models/index.ts | 160 ++ .../typescript-sdk/fetch-client/runtime.ts | 431 ++++ open-api/typescript-sdk/fetch.ts | 1 + open-api/typescript-sdk/index.ts | 4 - open-api/typescript-sdk/package.json | 21 +- .../{tsconfig.json => tsconfig.axios.json} | 3 +- open-api/typescript-sdk/tsconfig.fetch.json | 12 + web/package-lock.json | 11 +- web/src/api/api.ts | 2 +- web/src/api/index.ts | 2 +- web/src/api/types.ts | 2 +- web/src/api/utils.ts | 2 +- 218 files changed, 22789 insertions(+), 237 deletions(-) rename open-api/typescript-sdk/{client => axios-client}/.gitignore (100%) rename open-api/typescript-sdk/{client => axios-client}/.npmignore (100%) rename open-api/typescript-sdk/{client => axios-client}/.openapi-generator-ignore (100%) rename open-api/typescript-sdk/{client => axios-client}/.openapi-generator/FILES (76%) rename open-api/typescript-sdk/{client => axios-client}/.openapi-generator/VERSION (100%) rename open-api/typescript-sdk/{client => axios-client}/api.ts (100%) rename open-api/typescript-sdk/{client => axios-client}/base.ts (100%) rename open-api/typescript-sdk/{client => axios-client}/common.ts (100%) rename open-api/typescript-sdk/{client => axios-client}/configuration.ts (100%) rename open-api/typescript-sdk/{client => axios-client}/git_push.sh (100%) rename open-api/typescript-sdk/{client => axios-client}/index.ts (100%) create mode 100644 open-api/typescript-sdk/axios.ts create mode 100644 open-api/typescript-sdk/fetch-client/.openapi-generator-ignore create mode 100644 open-api/typescript-sdk/fetch-client/.openapi-generator/FILES create mode 100644 open-api/typescript-sdk/fetch-client/.openapi-generator/VERSION create mode 100644 open-api/typescript-sdk/fetch-client/apis/APIKeyApi.ts create mode 100644 open-api/typescript-sdk/fetch-client/apis/ActivityApi.ts create mode 100644 open-api/typescript-sdk/fetch-client/apis/AlbumApi.ts create mode 100644 open-api/typescript-sdk/fetch-client/apis/AssetApi.ts create mode 100644 open-api/typescript-sdk/fetch-client/apis/AuditApi.ts create mode 100644 open-api/typescript-sdk/fetch-client/apis/AuthenticationApi.ts create mode 100644 open-api/typescript-sdk/fetch-client/apis/DownloadApi.ts create mode 100644 open-api/typescript-sdk/fetch-client/apis/FaceApi.ts create mode 100644 open-api/typescript-sdk/fetch-client/apis/JobApi.ts create mode 100644 open-api/typescript-sdk/fetch-client/apis/LibraryApi.ts create mode 100644 open-api/typescript-sdk/fetch-client/apis/OAuthApi.ts create mode 100644 open-api/typescript-sdk/fetch-client/apis/PartnerApi.ts create mode 100644 open-api/typescript-sdk/fetch-client/apis/PersonApi.ts create mode 100644 open-api/typescript-sdk/fetch-client/apis/SearchApi.ts create mode 100644 open-api/typescript-sdk/fetch-client/apis/ServerInfoApi.ts create mode 100644 open-api/typescript-sdk/fetch-client/apis/SharedLinkApi.ts create mode 100644 open-api/typescript-sdk/fetch-client/apis/SystemConfigApi.ts create mode 100644 open-api/typescript-sdk/fetch-client/apis/TagApi.ts create mode 100644 open-api/typescript-sdk/fetch-client/apis/TrashApi.ts create mode 100644 open-api/typescript-sdk/fetch-client/apis/UserApi.ts create mode 100644 open-api/typescript-sdk/fetch-client/apis/index.ts create mode 100644 open-api/typescript-sdk/fetch-client/index.ts create mode 100644 open-api/typescript-sdk/fetch-client/models/APIKeyCreateDto.ts create mode 100644 open-api/typescript-sdk/fetch-client/models/APIKeyCreateResponseDto.ts create mode 100644 open-api/typescript-sdk/fetch-client/models/APIKeyResponseDto.ts create mode 100644 open-api/typescript-sdk/fetch-client/models/APIKeyUpdateDto.ts create mode 100644 open-api/typescript-sdk/fetch-client/models/ActivityCreateDto.ts create mode 100644 open-api/typescript-sdk/fetch-client/models/ActivityResponseDto.ts create mode 100644 open-api/typescript-sdk/fetch-client/models/ActivityStatisticsResponseDto.ts create mode 100644 open-api/typescript-sdk/fetch-client/models/AddUsersDto.ts create mode 100644 open-api/typescript-sdk/fetch-client/models/AlbumCountResponseDto.ts create mode 100644 open-api/typescript-sdk/fetch-client/models/AlbumResponseDto.ts create mode 100644 open-api/typescript-sdk/fetch-client/models/AllJobStatusResponseDto.ts create mode 100644 open-api/typescript-sdk/fetch-client/models/AssetBulkDeleteDto.ts create mode 100644 open-api/typescript-sdk/fetch-client/models/AssetBulkUpdateDto.ts create mode 100644 open-api/typescript-sdk/fetch-client/models/AssetBulkUploadCheckDto.ts create mode 100644 open-api/typescript-sdk/fetch-client/models/AssetBulkUploadCheckItem.ts create mode 100644 open-api/typescript-sdk/fetch-client/models/AssetBulkUploadCheckResponseDto.ts create mode 100644 open-api/typescript-sdk/fetch-client/models/AssetBulkUploadCheckResult.ts create mode 100644 open-api/typescript-sdk/fetch-client/models/AssetFaceResponseDto.ts create mode 100644 open-api/typescript-sdk/fetch-client/models/AssetFaceUpdateDto.ts create mode 100644 open-api/typescript-sdk/fetch-client/models/AssetFaceUpdateItem.ts create mode 100644 open-api/typescript-sdk/fetch-client/models/AssetFaceWithoutPersonResponseDto.ts create mode 100644 open-api/typescript-sdk/fetch-client/models/AssetFileUploadResponseDto.ts create mode 100644 open-api/typescript-sdk/fetch-client/models/AssetIdsDto.ts create mode 100644 open-api/typescript-sdk/fetch-client/models/AssetIdsResponseDto.ts create mode 100644 open-api/typescript-sdk/fetch-client/models/AssetJobName.ts create mode 100644 open-api/typescript-sdk/fetch-client/models/AssetJobsDto.ts create mode 100644 open-api/typescript-sdk/fetch-client/models/AssetOrder.ts create mode 100644 open-api/typescript-sdk/fetch-client/models/AssetResponseDto.ts create mode 100644 open-api/typescript-sdk/fetch-client/models/AssetStatsResponseDto.ts create mode 100644 open-api/typescript-sdk/fetch-client/models/AssetTypeEnum.ts create mode 100644 open-api/typescript-sdk/fetch-client/models/AudioCodec.ts create mode 100644 open-api/typescript-sdk/fetch-client/models/AuditDeletesResponseDto.ts create mode 100644 open-api/typescript-sdk/fetch-client/models/AuthDeviceResponseDto.ts create mode 100644 open-api/typescript-sdk/fetch-client/models/BulkIdResponseDto.ts create mode 100644 open-api/typescript-sdk/fetch-client/models/BulkIdsDto.ts create mode 100644 open-api/typescript-sdk/fetch-client/models/CLIPConfig.ts create mode 100644 open-api/typescript-sdk/fetch-client/models/CLIPMode.ts create mode 100644 open-api/typescript-sdk/fetch-client/models/CQMode.ts create mode 100644 open-api/typescript-sdk/fetch-client/models/ChangePasswordDto.ts create mode 100644 open-api/typescript-sdk/fetch-client/models/CheckExistingAssetsDto.ts create mode 100644 open-api/typescript-sdk/fetch-client/models/CheckExistingAssetsResponseDto.ts create mode 100644 open-api/typescript-sdk/fetch-client/models/Colorspace.ts create mode 100644 open-api/typescript-sdk/fetch-client/models/CreateAlbumDto.ts create mode 100644 open-api/typescript-sdk/fetch-client/models/CreateLibraryDto.ts create mode 100644 open-api/typescript-sdk/fetch-client/models/CreateProfileImageResponseDto.ts create mode 100644 open-api/typescript-sdk/fetch-client/models/CreateTagDto.ts create mode 100644 open-api/typescript-sdk/fetch-client/models/CreateUserDto.ts create mode 100644 open-api/typescript-sdk/fetch-client/models/CuratedLocationsResponseDto.ts create mode 100644 open-api/typescript-sdk/fetch-client/models/CuratedObjectsResponseDto.ts create mode 100644 open-api/typescript-sdk/fetch-client/models/DownloadArchiveInfo.ts create mode 100644 open-api/typescript-sdk/fetch-client/models/DownloadInfoDto.ts create mode 100644 open-api/typescript-sdk/fetch-client/models/DownloadResponseDto.ts create mode 100644 open-api/typescript-sdk/fetch-client/models/EntityType.ts create mode 100644 open-api/typescript-sdk/fetch-client/models/ExifResponseDto.ts create mode 100644 open-api/typescript-sdk/fetch-client/models/FaceDto.ts create mode 100644 open-api/typescript-sdk/fetch-client/models/FileChecksumDto.ts create mode 100644 open-api/typescript-sdk/fetch-client/models/FileChecksumResponseDto.ts create mode 100644 open-api/typescript-sdk/fetch-client/models/FileReportDto.ts create mode 100644 open-api/typescript-sdk/fetch-client/models/FileReportFixDto.ts create mode 100644 open-api/typescript-sdk/fetch-client/models/FileReportItemDto.ts create mode 100644 open-api/typescript-sdk/fetch-client/models/JobCommand.ts create mode 100644 open-api/typescript-sdk/fetch-client/models/JobCommandDto.ts create mode 100644 open-api/typescript-sdk/fetch-client/models/JobCountsDto.ts create mode 100644 open-api/typescript-sdk/fetch-client/models/JobName.ts create mode 100644 open-api/typescript-sdk/fetch-client/models/JobSettingsDto.ts create mode 100644 open-api/typescript-sdk/fetch-client/models/JobStatusDto.ts create mode 100644 open-api/typescript-sdk/fetch-client/models/LibraryResponseDto.ts create mode 100644 open-api/typescript-sdk/fetch-client/models/LibraryStatsResponseDto.ts create mode 100644 open-api/typescript-sdk/fetch-client/models/LibraryType.ts create mode 100644 open-api/typescript-sdk/fetch-client/models/LogLevel.ts create mode 100644 open-api/typescript-sdk/fetch-client/models/LoginCredentialDto.ts create mode 100644 open-api/typescript-sdk/fetch-client/models/LoginResponseDto.ts create mode 100644 open-api/typescript-sdk/fetch-client/models/LogoutResponseDto.ts create mode 100644 open-api/typescript-sdk/fetch-client/models/MapMarkerResponseDto.ts create mode 100644 open-api/typescript-sdk/fetch-client/models/MapTheme.ts create mode 100644 open-api/typescript-sdk/fetch-client/models/MemoryLaneResponseDto.ts create mode 100644 open-api/typescript-sdk/fetch-client/models/MergePersonDto.ts create mode 100644 open-api/typescript-sdk/fetch-client/models/ModelType.ts create mode 100644 open-api/typescript-sdk/fetch-client/models/OAuthAuthorizeResponseDto.ts create mode 100644 open-api/typescript-sdk/fetch-client/models/OAuthCallbackDto.ts create mode 100644 open-api/typescript-sdk/fetch-client/models/OAuthConfigDto.ts create mode 100644 open-api/typescript-sdk/fetch-client/models/OAuthConfigResponseDto.ts create mode 100644 open-api/typescript-sdk/fetch-client/models/PartnerResponseDto.ts create mode 100644 open-api/typescript-sdk/fetch-client/models/PathEntityType.ts create mode 100644 open-api/typescript-sdk/fetch-client/models/PathType.ts create mode 100644 open-api/typescript-sdk/fetch-client/models/PeopleResponseDto.ts create mode 100644 open-api/typescript-sdk/fetch-client/models/PeopleUpdateDto.ts create mode 100644 open-api/typescript-sdk/fetch-client/models/PeopleUpdateItem.ts create mode 100644 open-api/typescript-sdk/fetch-client/models/PersonResponseDto.ts create mode 100644 open-api/typescript-sdk/fetch-client/models/PersonStatisticsResponseDto.ts create mode 100644 open-api/typescript-sdk/fetch-client/models/PersonUpdateDto.ts create mode 100644 open-api/typescript-sdk/fetch-client/models/PersonWithFacesResponseDto.ts create mode 100644 open-api/typescript-sdk/fetch-client/models/QueueStatusDto.ts create mode 100644 open-api/typescript-sdk/fetch-client/models/ReactionLevel.ts create mode 100644 open-api/typescript-sdk/fetch-client/models/ReactionType.ts create mode 100644 open-api/typescript-sdk/fetch-client/models/RecognitionConfig.ts create mode 100644 open-api/typescript-sdk/fetch-client/models/ScanLibraryDto.ts create mode 100644 open-api/typescript-sdk/fetch-client/models/SearchAlbumResponseDto.ts create mode 100644 open-api/typescript-sdk/fetch-client/models/SearchAssetResponseDto.ts create mode 100644 open-api/typescript-sdk/fetch-client/models/SearchExploreItem.ts create mode 100644 open-api/typescript-sdk/fetch-client/models/SearchExploreResponseDto.ts create mode 100644 open-api/typescript-sdk/fetch-client/models/SearchFacetCountResponseDto.ts create mode 100644 open-api/typescript-sdk/fetch-client/models/SearchFacetResponseDto.ts create mode 100644 open-api/typescript-sdk/fetch-client/models/SearchResponseDto.ts create mode 100644 open-api/typescript-sdk/fetch-client/models/ServerConfigDto.ts create mode 100644 open-api/typescript-sdk/fetch-client/models/ServerFeaturesDto.ts create mode 100644 open-api/typescript-sdk/fetch-client/models/ServerInfoResponseDto.ts create mode 100644 open-api/typescript-sdk/fetch-client/models/ServerMediaTypesResponseDto.ts create mode 100644 open-api/typescript-sdk/fetch-client/models/ServerPingResponse.ts create mode 100644 open-api/typescript-sdk/fetch-client/models/ServerStatsResponseDto.ts create mode 100644 open-api/typescript-sdk/fetch-client/models/ServerThemeDto.ts create mode 100644 open-api/typescript-sdk/fetch-client/models/ServerVersionResponseDto.ts create mode 100644 open-api/typescript-sdk/fetch-client/models/SharedLinkCreateDto.ts create mode 100644 open-api/typescript-sdk/fetch-client/models/SharedLinkEditDto.ts create mode 100644 open-api/typescript-sdk/fetch-client/models/SharedLinkResponseDto.ts create mode 100644 open-api/typescript-sdk/fetch-client/models/SharedLinkType.ts create mode 100644 open-api/typescript-sdk/fetch-client/models/SignUpDto.ts create mode 100644 open-api/typescript-sdk/fetch-client/models/SmartInfoResponseDto.ts create mode 100644 open-api/typescript-sdk/fetch-client/models/SystemConfigDto.ts create mode 100644 open-api/typescript-sdk/fetch-client/models/SystemConfigFFmpegDto.ts create mode 100644 open-api/typescript-sdk/fetch-client/models/SystemConfigJobDto.ts create mode 100644 open-api/typescript-sdk/fetch-client/models/SystemConfigLibraryDto.ts create mode 100644 open-api/typescript-sdk/fetch-client/models/SystemConfigLibraryScanDto.ts create mode 100644 open-api/typescript-sdk/fetch-client/models/SystemConfigLibraryWatchDto.ts create mode 100644 open-api/typescript-sdk/fetch-client/models/SystemConfigLoggingDto.ts create mode 100644 open-api/typescript-sdk/fetch-client/models/SystemConfigMachineLearningDto.ts create mode 100644 open-api/typescript-sdk/fetch-client/models/SystemConfigMapDto.ts create mode 100644 open-api/typescript-sdk/fetch-client/models/SystemConfigNewVersionCheckDto.ts create mode 100644 open-api/typescript-sdk/fetch-client/models/SystemConfigOAuthDto.ts create mode 100644 open-api/typescript-sdk/fetch-client/models/SystemConfigPasswordLoginDto.ts create mode 100644 open-api/typescript-sdk/fetch-client/models/SystemConfigReverseGeocodingDto.ts create mode 100644 open-api/typescript-sdk/fetch-client/models/SystemConfigServerDto.ts create mode 100644 open-api/typescript-sdk/fetch-client/models/SystemConfigStorageTemplateDto.ts create mode 100644 open-api/typescript-sdk/fetch-client/models/SystemConfigTemplateStorageOptionDto.ts create mode 100644 open-api/typescript-sdk/fetch-client/models/SystemConfigThemeDto.ts create mode 100644 open-api/typescript-sdk/fetch-client/models/SystemConfigThumbnailDto.ts create mode 100644 open-api/typescript-sdk/fetch-client/models/SystemConfigTrashDto.ts create mode 100644 open-api/typescript-sdk/fetch-client/models/TagResponseDto.ts create mode 100644 open-api/typescript-sdk/fetch-client/models/TagTypeEnum.ts create mode 100644 open-api/typescript-sdk/fetch-client/models/ThumbnailFormat.ts create mode 100644 open-api/typescript-sdk/fetch-client/models/TimeBucketResponseDto.ts create mode 100644 open-api/typescript-sdk/fetch-client/models/TimeBucketSize.ts create mode 100644 open-api/typescript-sdk/fetch-client/models/ToneMapping.ts create mode 100644 open-api/typescript-sdk/fetch-client/models/TranscodeHWAccel.ts create mode 100644 open-api/typescript-sdk/fetch-client/models/TranscodePolicy.ts create mode 100644 open-api/typescript-sdk/fetch-client/models/UpdateAlbumDto.ts create mode 100644 open-api/typescript-sdk/fetch-client/models/UpdateAssetDto.ts create mode 100644 open-api/typescript-sdk/fetch-client/models/UpdateLibraryDto.ts create mode 100644 open-api/typescript-sdk/fetch-client/models/UpdatePartnerDto.ts create mode 100644 open-api/typescript-sdk/fetch-client/models/UpdateStackParentDto.ts create mode 100644 open-api/typescript-sdk/fetch-client/models/UpdateTagDto.ts create mode 100644 open-api/typescript-sdk/fetch-client/models/UpdateUserDto.ts create mode 100644 open-api/typescript-sdk/fetch-client/models/UsageByUserDto.ts create mode 100644 open-api/typescript-sdk/fetch-client/models/UserAvatarColor.ts create mode 100644 open-api/typescript-sdk/fetch-client/models/UserDto.ts create mode 100644 open-api/typescript-sdk/fetch-client/models/UserResponseDto.ts create mode 100644 open-api/typescript-sdk/fetch-client/models/ValidateAccessTokenResponseDto.ts create mode 100644 open-api/typescript-sdk/fetch-client/models/VideoCodec.ts create mode 100644 open-api/typescript-sdk/fetch-client/models/index.ts create mode 100644 open-api/typescript-sdk/fetch-client/runtime.ts create mode 100644 open-api/typescript-sdk/fetch.ts delete mode 100644 open-api/typescript-sdk/index.ts rename open-api/typescript-sdk/{tsconfig.json => tsconfig.axios.json} (70%) create mode 100644 open-api/typescript-sdk/tsconfig.fetch.json diff --git a/cli/package-lock.json b/cli/package-lock.json index 7acfa36670..d564d1c28c 100644 --- a/cli/package-lock.json +++ b/cli/package-lock.json @@ -21,7 +21,6 @@ "@typescript-eslint/eslint-plugin": "^6.4.1", "@typescript-eslint/parser": "^6.4.1", "@vitest/coverage-v8": "^1.2.2", - "axios": "^1.6.7", "byte-size": "^8.1.1", "cli-progress": "^3.12.0", "commander": "^11.0.0", @@ -46,12 +45,17 @@ "version": "1.92.1", "dev": true, "license": "MIT", - "dependencies": { - "axios": "^1.6.7" - }, "devDependencies": { "@types/node": "^20.11.0", "typescript": "^5.3.3" + }, + "peerDependencies": { + "axios": "^1.6.7" + }, + "peerDependenciesMeta": { + "axios": { + "optional": true + } } }, "../server": { @@ -2127,23 +2131,6 @@ "integrity": "sha512-coglx5yIWuetakm3/1dsX9hxCNox22h7+V80RQOu2XUUMidtArxKoZoOtHUPuR84SycKTXzgGzAUR5hJxujyJQ==", "dev": true }, - "node_modules/asynckit": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", - "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==", - "dev": true - }, - "node_modules/axios": { - "version": "1.6.7", - "resolved": "https://registry.npmjs.org/axios/-/axios-1.6.7.tgz", - "integrity": "sha512-/hDJGff6/c7u0hDkvkGxR/oy6CbCs8ziCsC7SqmhjfozqiJGc8Z11wrv9z9lYfY4K8l+H9TpjcMDX0xOZmx+RA==", - "dev": true, - "dependencies": { - "follow-redirects": "^1.15.4", - "form-data": "^4.0.0", - "proxy-from-env": "^1.1.0" - } - }, "node_modules/b4a": { "version": "1.6.4", "resolved": "https://registry.npmjs.org/b4a/-/b4a-1.6.4.tgz", @@ -2464,18 +2451,6 @@ "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", "dev": true }, - "node_modules/combined-stream": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", - "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", - "dev": true, - "dependencies": { - "delayed-stream": "~1.0.0" - }, - "engines": { - "node": ">= 0.8" - } - }, "node_modules/commander": { "version": "11.1.0", "resolved": "https://registry.npmjs.org/commander/-/commander-11.1.0.tgz", @@ -2620,15 +2595,6 @@ "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", "dev": true }, - "node_modules/delayed-stream": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", - "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==", - "dev": true, - "engines": { - "node": ">=0.4.0" - } - }, "node_modules/diff-sequences": { "version": "29.6.3", "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-29.6.3.tgz", @@ -3187,26 +3153,6 @@ "integrity": "sha512-36yxDn5H7OFZQla0/jFJmbIKTdZAQHngCedGxiMmpNfEZM0sdEeT+WczLQrjK6D7o2aiyLYDnkw0R3JK0Qv1RQ==", "dev": true }, - "node_modules/follow-redirects": { - "version": "1.15.5", - "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.5.tgz", - "integrity": "sha512-vSFWUON1B+yAw1VN4xMfxgn5fTUiaOzAJCKBwIIgT/+7CuGy9+r+5gITvP62j3RmaD5Ph65UaERdOSRGUzZtgw==", - "dev": true, - "funding": [ - { - "type": "individual", - "url": "https://github.com/sponsors/RubenVerborgh" - } - ], - "engines": { - "node": ">=4.0" - }, - "peerDependenciesMeta": { - "debug": { - "optional": true - } - } - }, "node_modules/foreground-child": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.1.1.tgz", @@ -3223,20 +3169,6 @@ "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/form-data": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz", - "integrity": "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==", - "dev": true, - "dependencies": { - "asynckit": "^0.4.0", - "combined-stream": "^1.0.8", - "mime-types": "^2.1.12" - }, - "engines": { - "node": ">= 6" - } - }, "node_modules/fs-constants": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/fs-constants/-/fs-constants-1.0.0.tgz", @@ -3944,27 +3876,6 @@ "node": ">=8.6" } }, - "node_modules/mime-db": { - "version": "1.52.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", - "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", - "dev": true, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/mime-types": { - "version": "2.1.35", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", - "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", - "dev": true, - "dependencies": { - "mime-db": "1.52.0" - }, - "engines": { - "node": ">= 0.6" - } - }, "node_modules/min-indent": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/min-indent/-/min-indent-1.0.1.tgz", @@ -4472,12 +4383,6 @@ "url": "https://github.com/steveukx/properties?sponsor=1" } }, - "node_modules/proxy-from-env": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz", - "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==", - "dev": true - }, "node_modules/pump": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", @@ -6430,7 +6335,6 @@ "version": "file:../open-api/typescript-sdk", "requires": { "@types/node": "^20.11.0", - "axios": "^1.6.7", "typescript": "^5.3.3" } }, @@ -7326,23 +7230,6 @@ "integrity": "sha512-coglx5yIWuetakm3/1dsX9hxCNox22h7+V80RQOu2XUUMidtArxKoZoOtHUPuR84SycKTXzgGzAUR5hJxujyJQ==", "dev": true }, - "asynckit": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", - "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==", - "dev": true - }, - "axios": { - "version": "1.6.7", - "resolved": "https://registry.npmjs.org/axios/-/axios-1.6.7.tgz", - "integrity": "sha512-/hDJGff6/c7u0hDkvkGxR/oy6CbCs8ziCsC7SqmhjfozqiJGc8Z11wrv9z9lYfY4K8l+H9TpjcMDX0xOZmx+RA==", - "dev": true, - "requires": { - "follow-redirects": "^1.15.4", - "form-data": "^4.0.0", - "proxy-from-env": "^1.1.0" - } - }, "b4a": { "version": "1.6.4", "resolved": "https://registry.npmjs.org/b4a/-/b4a-1.6.4.tgz", @@ -7552,15 +7439,6 @@ "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", "dev": true }, - "combined-stream": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", - "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", - "dev": true, - "requires": { - "delayed-stream": "~1.0.0" - } - }, "commander": { "version": "11.1.0", "resolved": "https://registry.npmjs.org/commander/-/commander-11.1.0.tgz", @@ -7668,12 +7546,6 @@ "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", "dev": true }, - "delayed-stream": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", - "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==", - "dev": true - }, "diff-sequences": { "version": "29.6.3", "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-29.6.3.tgz", @@ -8101,12 +7973,6 @@ "integrity": "sha512-36yxDn5H7OFZQla0/jFJmbIKTdZAQHngCedGxiMmpNfEZM0sdEeT+WczLQrjK6D7o2aiyLYDnkw0R3JK0Qv1RQ==", "dev": true }, - "follow-redirects": { - "version": "1.15.5", - "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.5.tgz", - "integrity": "sha512-vSFWUON1B+yAw1VN4xMfxgn5fTUiaOzAJCKBwIIgT/+7CuGy9+r+5gITvP62j3RmaD5Ph65UaERdOSRGUzZtgw==", - "dev": true - }, "foreground-child": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.1.1.tgz", @@ -8117,17 +7983,6 @@ "signal-exit": "^4.0.1" } }, - "form-data": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz", - "integrity": "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==", - "dev": true, - "requires": { - "asynckit": "^0.4.0", - "combined-stream": "^1.0.8", - "mime-types": "^2.1.12" - } - }, "fs-constants": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/fs-constants/-/fs-constants-1.0.0.tgz", @@ -8762,21 +8617,6 @@ "picomatch": "^2.3.1" } }, - "mime-db": { - "version": "1.52.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", - "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", - "dev": true - }, - "mime-types": { - "version": "2.1.35", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", - "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", - "dev": true, - "requires": { - "mime-db": "1.52.0" - } - }, "min-indent": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/min-indent/-/min-indent-1.0.1.tgz", @@ -9137,12 +8977,6 @@ "mkdirp": "^1.0.4" } }, - "proxy-from-env": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz", - "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==", - "dev": true - }, "pump": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", diff --git a/cli/package.json b/cli/package.json index a4bb184a44..a20070f610 100644 --- a/cli/package.json +++ b/cli/package.json @@ -22,7 +22,6 @@ "@typescript-eslint/eslint-plugin": "^6.4.1", "@typescript-eslint/parser": "^6.4.1", "@vitest/coverage-v8": "^1.2.2", - "axios": "^1.6.7", "byte-size": "^8.1.1", "cli-progress": "^3.12.0", "commander": "^11.0.0", diff --git a/cli/src/commands/server-info.command.ts b/cli/src/commands/server-info.command.ts index c9d454d59e..f4a256eda8 100644 --- a/cli/src/commands/server-info.command.ts +++ b/cli/src/commands/server-info.command.ts @@ -3,9 +3,9 @@ import { BaseCommand } from './base-command'; export class ServerInfoCommand extends BaseCommand { public async run() { await this.connect(); - const { data: versionInfo } = await this.immichApi.serverInfoApi.getServerVersion(); - const { data: mediaTypes } = await this.immichApi.serverInfoApi.getSupportedMediaTypes(); - const { data: statistics } = await this.immichApi.assetApi.getAssetStatistics(); + const versionInfo = await this.immichApi.serverInfoApi.getServerVersion(); + const mediaTypes = await this.immichApi.serverInfoApi.getSupportedMediaTypes(); + const statistics = await this.immichApi.assetApi.getAssetStatistics(); console.log(`Server Version: ${versionInfo.major}.${versionInfo.minor}.${versionInfo.patch}`); console.log(`Image Types: ${mediaTypes.image.map((extension) => extension.replace('.', ''))}`); diff --git a/cli/src/commands/upload.command.ts b/cli/src/commands/upload.command.ts index b5ea6aa0fd..7933775faf 100644 --- a/cli/src/commands/upload.command.ts +++ b/cli/src/commands/upload.command.ts @@ -1,4 +1,3 @@ -import axios, { AxiosRequestConfig, AxiosResponse } from 'axios'; import byteSize from 'byte-size'; import cliProgress from 'cli-progress'; import fs, { createReadStream } from 'node:fs'; @@ -114,7 +113,7 @@ export class UploadCommand extends BaseCommand { await this.connect(); const formatResponse = await this.immichApi.serverInfoApi.getSupportedMediaTypes(); - const crawlService = new CrawlService(formatResponse.data.image, formatResponse.data.video); + const crawlService = new CrawlService(formatResponse.image, formatResponse.video); const inputFiles: string[] = []; for (const pathArgument of paths) { @@ -163,7 +162,7 @@ export class UploadCommand extends BaseCommand { } } - const { data: existingAlbums } = await this.immichApi.albumApi.getAllAlbums(); + const existingAlbums = await this.immichApi.albumApi.getAllAlbums(); uploadProgress.start(totalSize, 0); uploadProgress.update({ value_formatted: 0, total_formatted: byteSize(totalSize) }); @@ -186,11 +185,11 @@ export class UploadCommand extends BaseCommand { assetBulkUploadCheckDto, }); - skipUpload = checkResponse.data.results[0].action === 'reject'; + skipUpload = checkResponse.results[0].action === 'reject'; - const isDuplicate = checkResponse.data.results[0].reason === 'duplicate'; + const isDuplicate = checkResponse.results[0].reason === 'duplicate'; if (isDuplicate) { - existingAssetId = checkResponse.data.results[0].assetId; + existingAssetId = checkResponse.results[0].assetId; } skipAsset = skipUpload && !isDuplicate; @@ -199,8 +198,9 @@ export class UploadCommand extends BaseCommand { if (!skipAsset && !options.dryRun) { if (!skipUpload) { const formData = await asset.getUploadFormData(); - const { data } = await this.uploadAsset(formData); - existingAssetId = data.id; + const response = await this.uploadAsset(formData); + const json = await response.json(); + existingAssetId = json.id; uploadCounter++; totalSizeUploaded += asset.fileSize; } @@ -208,10 +208,10 @@ export class UploadCommand extends BaseCommand { if ((options.album || options.albumName) && asset.albumName !== undefined) { let album = existingAlbums.find((album) => album.albumName === asset.albumName); if (!album) { - const { data } = await this.immichApi.albumApi.createAlbum({ + const response = await this.immichApi.albumApi.createAlbum({ createAlbumDto: { albumName: asset.albumName }, }); - album = data; + album = response; existingAlbums.push(album); } @@ -259,21 +259,20 @@ export class UploadCommand extends BaseCommand { } } - private async uploadAsset(data: FormData): Promise { + private async uploadAsset(data: FormData): Promise { const url = this.immichApi.instanceUrl + '/asset/upload'; - const config: AxiosRequestConfig = { + const response = await fetch(url, { method: 'post', - maxRedirects: 0, - url, + redirect: 'error', headers: { 'x-api-key': this.immichApi.apiKey, }, - maxContentLength: Number.POSITIVE_INFINITY, - maxBodyLength: Number.POSITIVE_INFINITY, - data, - }; - - return axios(config); + body: data, + }); + if (response.status !== 200 && response.status !== 201) { + throw new Error(await response.text()); + } + return response; } } diff --git a/cli/src/services/api.service.ts b/cli/src/services/api.service.ts index 8110d92d29..5626a50659 100644 --- a/cli/src/services/api.service.ts +++ b/cli/src/services/api.service.ts @@ -10,7 +10,6 @@ import { SystemConfigApi, UserApi, } from '@immich/sdk'; -import FormData from 'form-data'; export class ImmichApi { public userApi: UserApi; @@ -31,12 +30,9 @@ export class ImmichApi { ) { this.config = new Configuration({ basePath: instanceUrl, - baseOptions: { - headers: { - 'x-api-key': apiKey, - }, + headers: { + 'x-api-key': apiKey, }, - formDataCtor: FormData, }); this.userApi = new UserApi(this.config); @@ -52,6 +48,9 @@ export class ImmichApi { setApiKey(apiKey: string) { this.apiKey = apiKey; - this.config.baseOptions.headers['x-api-key'] = apiKey; + if (!this.config.headers) { + throw new Error('missing headers'); + } + this.config.headers['x-api-key'] = apiKey; } } diff --git a/cli/src/services/session.service.spec.ts b/cli/src/services/session.service.spec.ts index dbb3d7201b..7013e9f1eb 100644 --- a/cli/src/services/session.service.spec.ts +++ b/cli/src/services/session.service.spec.ts @@ -12,8 +12,8 @@ import { spyOnConsole, } from '../../test/cli-test-utils'; -const mockPingServer = vi.fn(() => Promise.resolve({ data: { res: 'pong' } })); -const mockUserInfo = vi.fn(() => Promise.resolve({ data: { email: 'admin@example.com' } })); +const mockPingServer = vi.fn(() => Promise.resolve({ res: 'pong' })); +const mockUserInfo = vi.fn(() => Promise.resolve({ email: 'admin@example.com' })); vi.mock('@immich/sdk', async () => ({ ...(await vi.importActual('@immich/sdk')), diff --git a/cli/src/services/session.service.ts b/cli/src/services/session.service.ts index 9276a47210..05df2ec6e3 100644 --- a/cli/src/services/session.service.ts +++ b/cli/src/services/session.service.ts @@ -51,7 +51,7 @@ export class SessionService { const api = new ImmichApi(instanceUrl, apiKey); - const { data: pingResponse } = await api.serverInfoApi.pingServer().catch((error) => { + const pingResponse = await api.serverInfoApi.pingServer().catch((error) => { throw new Error(`Failed to connect to server ${api.instanceUrl}: ${error.message}`); }); @@ -68,7 +68,7 @@ export class SessionService { const api = new ImmichApi(instanceUrl, apiKey); // Check if server and api key are valid - const { data: userInfo } = await api.userApi.getMyUserInfo().catch((error) => { + const userInfo = await api.userApi.getMyUserInfo().catch((error) => { throw new LoginError(`Failed to connect to server ${instanceUrl}: ${error.message}`); }); diff --git a/cli/test/cli-test-utils.ts b/cli/test/cli-test-utils.ts index 3063e490f4..405b7794df 100644 --- a/cli/test/cli-test-utils.ts +++ b/cli/test/cli-test-utils.ts @@ -14,10 +14,10 @@ export const setup = async () => { await api.authenticationApi.signUpAdmin({ signUpDto: { email: 'cli@immich.app', password: 'password', name: 'Administrator' }, }); - const { data: admin } = await api.authenticationApi.login({ + const admin = await api.authenticationApi.login({ loginCredentialDto: { email: 'cli@immich.app', password: 'password' }, }); - const { data: apiKey } = await api.keyApi.createApiKey( + const apiKey = await api.keyApi.createApiKey( { aPIKeyCreateDto: { name: 'CLI Test' } }, { headers: { Authorization: `Bearer ${admin.accessToken}` } }, ); diff --git a/cli/test/e2e/login-key.e2e-spec.ts b/cli/test/e2e/login-key.e2e-spec.ts index d1e7f780e3..8b215def75 100644 --- a/cli/test/e2e/login-key.e2e-spec.ts +++ b/cli/test/e2e/login-key.e2e-spec.ts @@ -32,7 +32,7 @@ describe(`login-key (e2e)`, () => { it('should error when providing an invalid API key', async () => { await expect(new LoginCommand(CLI_BASE_OPTIONS).run(instanceUrl, 'invalid')).rejects.toThrow( - `Failed to connect to server ${instanceUrl}: Request failed with status code 401`, + `Failed to connect to server ${instanceUrl}: Response returned an error code`, ); }); diff --git a/cli/test/e2e/upload.e2e-spec.ts b/cli/test/e2e/upload.e2e-spec.ts index e2e38b9d85..0c6e87ce5a 100644 --- a/cli/test/e2e/upload.e2e-spec.ts +++ b/cli/test/e2e/upload.e2e-spec.ts @@ -26,13 +26,13 @@ describe(`upload (e2e)`, () => { it('should upload a folder recursively', async () => { await new UploadCommand(CLI_BASE_OPTIONS).run([`${IMMICH_TEST_ASSET_PATH}/albums/nature/`], { recursive: true }); - const { data: assets } = await api.assetApi.getAllAssets({}, { headers: { 'x-api-key': api.apiKey } }); + const assets = await api.assetApi.getAllAssets({}, { headers: { 'x-api-key': api.apiKey } }); expect(assets.length).toBeGreaterThan(4); }); it('should not create a new album', async () => { await new UploadCommand(CLI_BASE_OPTIONS).run([`${IMMICH_TEST_ASSET_PATH}/albums/nature/`], { recursive: true }); - const { data: albums } = await api.albumApi.getAllAlbums({}, { headers: { 'x-api-key': api.apiKey } }); + const albums = await api.albumApi.getAllAlbums({}, { headers: { 'x-api-key': api.apiKey } }); expect(albums.length).toEqual(0); }); @@ -42,7 +42,7 @@ describe(`upload (e2e)`, () => { album: true, }); - const { data: albums } = await api.albumApi.getAllAlbums({}, { headers: { 'x-api-key': api.apiKey } }); + const albums = await api.albumApi.getAllAlbums({}, { headers: { 'x-api-key': api.apiKey } }); expect(albums.length).toEqual(1); const natureAlbum = albums[0]; expect(natureAlbum.albumName).toEqual('nature'); @@ -59,7 +59,7 @@ describe(`upload (e2e)`, () => { album: true, }); - const { data: albums } = await api.albumApi.getAllAlbums({}, { headers: { 'x-api-key': api.apiKey } }); + const albums = await api.albumApi.getAllAlbums({}, { headers: { 'x-api-key': api.apiKey } }); expect(albums.length).toEqual(1); const natureAlbum = albums[0]; expect(natureAlbum.albumName).toEqual('nature'); @@ -71,7 +71,7 @@ describe(`upload (e2e)`, () => { albumName: 'testAlbum', }); - const { data: albums } = await api.albumApi.getAllAlbums({}, { headers: { 'x-api-key': api.apiKey } }); + const albums = await api.albumApi.getAllAlbums({}, { headers: { 'x-api-key': api.apiKey } }); expect(albums.length).toEqual(1); const testAlbum = albums[0]; expect(testAlbum.albumName).toEqual('testAlbum'); diff --git a/open-api/bin/generate-open-api.sh b/open-api/bin/generate-open-api.sh index b6c1541906..efc83aee9c 100755 --- a/open-api/bin/generate-open-api.sh +++ b/open-api/bin/generate-open-api.sh @@ -18,7 +18,8 @@ function dart { function typescript { rm -rf ./typescript-sdk/client - npx --yes @openapitools/openapi-generator-cli generate -g typescript-axios -i ./immich-openapi-specs.json -o ./typescript-sdk/client --additional-properties=useSingleRequestParameter=true + npx --yes @openapitools/openapi-generator-cli generate -g typescript-axios -i ./immich-openapi-specs.json -o ./typescript-sdk/axios-client --additional-properties=useSingleRequestParameter=true,supportsES6=true + npx --yes @openapitools/openapi-generator-cli generate -g typescript-fetch -i ./immich-openapi-specs.json -o ./typescript-sdk/fetch-client --additional-properties=useSingleRequestParameter=true,supportsES6=true npm --prefix typescript-sdk ci && npm --prefix typescript-sdk run build } diff --git a/open-api/typescript-sdk/client/.gitignore b/open-api/typescript-sdk/axios-client/.gitignore similarity index 100% rename from open-api/typescript-sdk/client/.gitignore rename to open-api/typescript-sdk/axios-client/.gitignore diff --git a/open-api/typescript-sdk/client/.npmignore b/open-api/typescript-sdk/axios-client/.npmignore similarity index 100% rename from open-api/typescript-sdk/client/.npmignore rename to open-api/typescript-sdk/axios-client/.npmignore diff --git a/open-api/typescript-sdk/client/.openapi-generator-ignore b/open-api/typescript-sdk/axios-client/.openapi-generator-ignore similarity index 100% rename from open-api/typescript-sdk/client/.openapi-generator-ignore rename to open-api/typescript-sdk/axios-client/.openapi-generator-ignore diff --git a/open-api/typescript-sdk/client/.openapi-generator/FILES b/open-api/typescript-sdk/axios-client/.openapi-generator/FILES similarity index 76% rename from open-api/typescript-sdk/client/.openapi-generator/FILES rename to open-api/typescript-sdk/axios-client/.openapi-generator/FILES index 16b445eee6..a80cd4f07b 100644 --- a/open-api/typescript-sdk/client/.openapi-generator/FILES +++ b/open-api/typescript-sdk/axios-client/.openapi-generator/FILES @@ -1,6 +1,5 @@ .gitignore .npmignore -.openapi-generator-ignore api.ts base.ts common.ts diff --git a/open-api/typescript-sdk/client/.openapi-generator/VERSION b/open-api/typescript-sdk/axios-client/.openapi-generator/VERSION similarity index 100% rename from open-api/typescript-sdk/client/.openapi-generator/VERSION rename to open-api/typescript-sdk/axios-client/.openapi-generator/VERSION diff --git a/open-api/typescript-sdk/client/api.ts b/open-api/typescript-sdk/axios-client/api.ts similarity index 100% rename from open-api/typescript-sdk/client/api.ts rename to open-api/typescript-sdk/axios-client/api.ts diff --git a/open-api/typescript-sdk/client/base.ts b/open-api/typescript-sdk/axios-client/base.ts similarity index 100% rename from open-api/typescript-sdk/client/base.ts rename to open-api/typescript-sdk/axios-client/base.ts diff --git a/open-api/typescript-sdk/client/common.ts b/open-api/typescript-sdk/axios-client/common.ts similarity index 100% rename from open-api/typescript-sdk/client/common.ts rename to open-api/typescript-sdk/axios-client/common.ts diff --git a/open-api/typescript-sdk/client/configuration.ts b/open-api/typescript-sdk/axios-client/configuration.ts similarity index 100% rename from open-api/typescript-sdk/client/configuration.ts rename to open-api/typescript-sdk/axios-client/configuration.ts diff --git a/open-api/typescript-sdk/client/git_push.sh b/open-api/typescript-sdk/axios-client/git_push.sh similarity index 100% rename from open-api/typescript-sdk/client/git_push.sh rename to open-api/typescript-sdk/axios-client/git_push.sh diff --git a/open-api/typescript-sdk/client/index.ts b/open-api/typescript-sdk/axios-client/index.ts similarity index 100% rename from open-api/typescript-sdk/client/index.ts rename to open-api/typescript-sdk/axios-client/index.ts diff --git a/open-api/typescript-sdk/axios.ts b/open-api/typescript-sdk/axios.ts new file mode 100644 index 0000000000..9cda702043 --- /dev/null +++ b/open-api/typescript-sdk/axios.ts @@ -0,0 +1,4 @@ +export * from './axios-client'; +export * as base from './axios-client/base'; +export * as configuration from './axios-client/configuration'; +export * as common from './axios-client/common'; diff --git a/open-api/typescript-sdk/fetch-client/.openapi-generator-ignore b/open-api/typescript-sdk/fetch-client/.openapi-generator-ignore new file mode 100644 index 0000000000..7484ee590a --- /dev/null +++ b/open-api/typescript-sdk/fetch-client/.openapi-generator-ignore @@ -0,0 +1,23 @@ +# OpenAPI Generator Ignore +# Generated by openapi-generator https://github.com/openapitools/openapi-generator + +# Use this file to prevent files from being overwritten by the generator. +# The patterns follow closely to .gitignore or .dockerignore. + +# As an example, the C# client generator defines ApiClient.cs. +# You can make changes and tell OpenAPI Generator to ignore just this file by uncommenting the following line: +#ApiClient.cs + +# You can match any string of characters against a directory, file or extension with a single asterisk (*): +#foo/*/qux +# The above matches foo/bar/qux and foo/baz/qux, but not foo/bar/baz/qux + +# You can recursively match patterns against a directory, file or extension with a double asterisk (**): +#foo/**/qux +# This matches foo/bar/qux, foo/baz/qux, and foo/bar/baz/qux + +# You can also negate patterns with an exclamation (!). +# For example, you can ignore all files in a docs folder with the file extension .md: +#docs/*.md +# Then explicitly reverse the ignore rule for a single file: +#!docs/README.md diff --git a/open-api/typescript-sdk/fetch-client/.openapi-generator/FILES b/open-api/typescript-sdk/fetch-client/.openapi-generator/FILES new file mode 100644 index 0000000000..3f9fcad44e --- /dev/null +++ b/open-api/typescript-sdk/fetch-client/.openapi-generator/FILES @@ -0,0 +1,182 @@ +apis/APIKeyApi.ts +apis/ActivityApi.ts +apis/AlbumApi.ts +apis/AssetApi.ts +apis/AuditApi.ts +apis/AuthenticationApi.ts +apis/DownloadApi.ts +apis/FaceApi.ts +apis/JobApi.ts +apis/LibraryApi.ts +apis/OAuthApi.ts +apis/PartnerApi.ts +apis/PersonApi.ts +apis/SearchApi.ts +apis/ServerInfoApi.ts +apis/SharedLinkApi.ts +apis/SystemConfigApi.ts +apis/TagApi.ts +apis/TrashApi.ts +apis/UserApi.ts +apis/index.ts +index.ts +models/APIKeyCreateDto.ts +models/APIKeyCreateResponseDto.ts +models/APIKeyResponseDto.ts +models/APIKeyUpdateDto.ts +models/ActivityCreateDto.ts +models/ActivityResponseDto.ts +models/ActivityStatisticsResponseDto.ts +models/AddUsersDto.ts +models/AlbumCountResponseDto.ts +models/AlbumResponseDto.ts +models/AllJobStatusResponseDto.ts +models/AssetBulkDeleteDto.ts +models/AssetBulkUpdateDto.ts +models/AssetBulkUploadCheckDto.ts +models/AssetBulkUploadCheckItem.ts +models/AssetBulkUploadCheckResponseDto.ts +models/AssetBulkUploadCheckResult.ts +models/AssetFaceResponseDto.ts +models/AssetFaceUpdateDto.ts +models/AssetFaceUpdateItem.ts +models/AssetFaceWithoutPersonResponseDto.ts +models/AssetFileUploadResponseDto.ts +models/AssetIdsDto.ts +models/AssetIdsResponseDto.ts +models/AssetJobName.ts +models/AssetJobsDto.ts +models/AssetOrder.ts +models/AssetResponseDto.ts +models/AssetStatsResponseDto.ts +models/AssetTypeEnum.ts +models/AudioCodec.ts +models/AuditDeletesResponseDto.ts +models/AuthDeviceResponseDto.ts +models/BulkIdResponseDto.ts +models/BulkIdsDto.ts +models/CLIPConfig.ts +models/CLIPMode.ts +models/CQMode.ts +models/ChangePasswordDto.ts +models/CheckExistingAssetsDto.ts +models/CheckExistingAssetsResponseDto.ts +models/Colorspace.ts +models/CreateAlbumDto.ts +models/CreateLibraryDto.ts +models/CreateProfileImageResponseDto.ts +models/CreateTagDto.ts +models/CreateUserDto.ts +models/CuratedLocationsResponseDto.ts +models/CuratedObjectsResponseDto.ts +models/DownloadArchiveInfo.ts +models/DownloadInfoDto.ts +models/DownloadResponseDto.ts +models/EntityType.ts +models/ExifResponseDto.ts +models/FaceDto.ts +models/FileChecksumDto.ts +models/FileChecksumResponseDto.ts +models/FileReportDto.ts +models/FileReportFixDto.ts +models/FileReportItemDto.ts +models/JobCommand.ts +models/JobCommandDto.ts +models/JobCountsDto.ts +models/JobName.ts +models/JobSettingsDto.ts +models/JobStatusDto.ts +models/LibraryResponseDto.ts +models/LibraryStatsResponseDto.ts +models/LibraryType.ts +models/LogLevel.ts +models/LoginCredentialDto.ts +models/LoginResponseDto.ts +models/LogoutResponseDto.ts +models/MapMarkerResponseDto.ts +models/MapTheme.ts +models/MemoryLaneResponseDto.ts +models/MergePersonDto.ts +models/ModelType.ts +models/OAuthAuthorizeResponseDto.ts +models/OAuthCallbackDto.ts +models/OAuthConfigDto.ts +models/OAuthConfigResponseDto.ts +models/PartnerResponseDto.ts +models/PathEntityType.ts +models/PathType.ts +models/PeopleResponseDto.ts +models/PeopleUpdateDto.ts +models/PeopleUpdateItem.ts +models/PersonResponseDto.ts +models/PersonStatisticsResponseDto.ts +models/PersonUpdateDto.ts +models/PersonWithFacesResponseDto.ts +models/QueueStatusDto.ts +models/ReactionLevel.ts +models/ReactionType.ts +models/RecognitionConfig.ts +models/ScanLibraryDto.ts +models/SearchAlbumResponseDto.ts +models/SearchAssetResponseDto.ts +models/SearchExploreItem.ts +models/SearchExploreResponseDto.ts +models/SearchFacetCountResponseDto.ts +models/SearchFacetResponseDto.ts +models/SearchResponseDto.ts +models/ServerConfigDto.ts +models/ServerFeaturesDto.ts +models/ServerInfoResponseDto.ts +models/ServerMediaTypesResponseDto.ts +models/ServerPingResponse.ts +models/ServerStatsResponseDto.ts +models/ServerThemeDto.ts +models/ServerVersionResponseDto.ts +models/SharedLinkCreateDto.ts +models/SharedLinkEditDto.ts +models/SharedLinkResponseDto.ts +models/SharedLinkType.ts +models/SignUpDto.ts +models/SmartInfoResponseDto.ts +models/SystemConfigDto.ts +models/SystemConfigFFmpegDto.ts +models/SystemConfigJobDto.ts +models/SystemConfigLibraryDto.ts +models/SystemConfigLibraryScanDto.ts +models/SystemConfigLibraryWatchDto.ts +models/SystemConfigLoggingDto.ts +models/SystemConfigMachineLearningDto.ts +models/SystemConfigMapDto.ts +models/SystemConfigNewVersionCheckDto.ts +models/SystemConfigOAuthDto.ts +models/SystemConfigPasswordLoginDto.ts +models/SystemConfigReverseGeocodingDto.ts +models/SystemConfigServerDto.ts +models/SystemConfigStorageTemplateDto.ts +models/SystemConfigTemplateStorageOptionDto.ts +models/SystemConfigThemeDto.ts +models/SystemConfigThumbnailDto.ts +models/SystemConfigTrashDto.ts +models/TagResponseDto.ts +models/TagTypeEnum.ts +models/ThumbnailFormat.ts +models/TimeBucketResponseDto.ts +models/TimeBucketSize.ts +models/ToneMapping.ts +models/TranscodeHWAccel.ts +models/TranscodePolicy.ts +models/UpdateAlbumDto.ts +models/UpdateAssetDto.ts +models/UpdateLibraryDto.ts +models/UpdatePartnerDto.ts +models/UpdateStackParentDto.ts +models/UpdateTagDto.ts +models/UpdateUserDto.ts +models/UsageByUserDto.ts +models/UserAvatarColor.ts +models/UserDto.ts +models/UserResponseDto.ts +models/ValidateAccessTokenResponseDto.ts +models/VideoCodec.ts +models/index.ts +runtime.ts diff --git a/open-api/typescript-sdk/fetch-client/.openapi-generator/VERSION b/open-api/typescript-sdk/fetch-client/.openapi-generator/VERSION new file mode 100644 index 0000000000..4b49d9bb63 --- /dev/null +++ b/open-api/typescript-sdk/fetch-client/.openapi-generator/VERSION @@ -0,0 +1 @@ +7.2.0 \ No newline at end of file diff --git a/open-api/typescript-sdk/fetch-client/apis/APIKeyApi.ts b/open-api/typescript-sdk/fetch-client/apis/APIKeyApi.ts new file mode 100644 index 0000000000..2a7b51f395 --- /dev/null +++ b/open-api/typescript-sdk/fetch-client/apis/APIKeyApi.ts @@ -0,0 +1,261 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * Immich + * Immich API + * + * The version of the OpenAPI document: 1.94.1 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + + +import * as runtime from '../runtime'; +import type { + APIKeyCreateDto, + APIKeyCreateResponseDto, + APIKeyResponseDto, + APIKeyUpdateDto, +} from '../models/index'; +import { + APIKeyCreateDtoFromJSON, + APIKeyCreateDtoToJSON, + APIKeyCreateResponseDtoFromJSON, + APIKeyCreateResponseDtoToJSON, + APIKeyResponseDtoFromJSON, + APIKeyResponseDtoToJSON, + APIKeyUpdateDtoFromJSON, + APIKeyUpdateDtoToJSON, +} from '../models/index'; + +export interface CreateApiKeyRequest { + aPIKeyCreateDto: APIKeyCreateDto; +} + +export interface DeleteApiKeyRequest { + id: string; +} + +export interface GetApiKeyRequest { + id: string; +} + +export interface UpdateApiKeyRequest { + id: string; + aPIKeyUpdateDto: APIKeyUpdateDto; +} + +/** + * + */ +export class APIKeyApi extends runtime.BaseAPI { + + /** + */ + async createApiKeyRaw(requestParameters: CreateApiKeyRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise> { + if (requestParameters.aPIKeyCreateDto === null || requestParameters.aPIKeyCreateDto === undefined) { + throw new runtime.RequiredError('aPIKeyCreateDto','Required parameter requestParameters.aPIKeyCreateDto was null or undefined when calling createApiKey.'); + } + + const queryParameters: any = {}; + + const headerParameters: runtime.HTTPHeaders = {}; + + headerParameters['Content-Type'] = 'application/json'; + + if (this.configuration && this.configuration.apiKey) { + headerParameters["x-api-key"] = this.configuration.apiKey("x-api-key"); // api_key authentication + } + + if (this.configuration && this.configuration.accessToken) { + const token = this.configuration.accessToken; + const tokenString = await token("bearer", []); + + if (tokenString) { + headerParameters["Authorization"] = `Bearer ${tokenString}`; + } + } + const response = await this.request({ + path: `/api-key`, + method: 'POST', + headers: headerParameters, + query: queryParameters, + body: APIKeyCreateDtoToJSON(requestParameters.aPIKeyCreateDto), + }, initOverrides); + + return new runtime.JSONApiResponse(response, (jsonValue) => APIKeyCreateResponseDtoFromJSON(jsonValue)); + } + + /** + */ + async createApiKey(requestParameters: CreateApiKeyRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise { + const response = await this.createApiKeyRaw(requestParameters, initOverrides); + return await response.value(); + } + + /** + */ + async deleteApiKeyRaw(requestParameters: DeleteApiKeyRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise> { + if (requestParameters.id === null || requestParameters.id === undefined) { + throw new runtime.RequiredError('id','Required parameter requestParameters.id was null or undefined when calling deleteApiKey.'); + } + + const queryParameters: any = {}; + + const headerParameters: runtime.HTTPHeaders = {}; + + if (this.configuration && this.configuration.apiKey) { + headerParameters["x-api-key"] = this.configuration.apiKey("x-api-key"); // api_key authentication + } + + if (this.configuration && this.configuration.accessToken) { + const token = this.configuration.accessToken; + const tokenString = await token("bearer", []); + + if (tokenString) { + headerParameters["Authorization"] = `Bearer ${tokenString}`; + } + } + const response = await this.request({ + path: `/api-key/{id}`.replace(`{${"id"}}`, encodeURIComponent(String(requestParameters.id))), + method: 'DELETE', + headers: headerParameters, + query: queryParameters, + }, initOverrides); + + return new runtime.VoidApiResponse(response); + } + + /** + */ + async deleteApiKey(requestParameters: DeleteApiKeyRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise { + await this.deleteApiKeyRaw(requestParameters, initOverrides); + } + + /** + */ + async getApiKeyRaw(requestParameters: GetApiKeyRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise> { + if (requestParameters.id === null || requestParameters.id === undefined) { + throw new runtime.RequiredError('id','Required parameter requestParameters.id was null or undefined when calling getApiKey.'); + } + + const queryParameters: any = {}; + + const headerParameters: runtime.HTTPHeaders = {}; + + if (this.configuration && this.configuration.apiKey) { + headerParameters["x-api-key"] = this.configuration.apiKey("x-api-key"); // api_key authentication + } + + if (this.configuration && this.configuration.accessToken) { + const token = this.configuration.accessToken; + const tokenString = await token("bearer", []); + + if (tokenString) { + headerParameters["Authorization"] = `Bearer ${tokenString}`; + } + } + const response = await this.request({ + path: `/api-key/{id}`.replace(`{${"id"}}`, encodeURIComponent(String(requestParameters.id))), + method: 'GET', + headers: headerParameters, + query: queryParameters, + }, initOverrides); + + return new runtime.JSONApiResponse(response, (jsonValue) => APIKeyResponseDtoFromJSON(jsonValue)); + } + + /** + */ + async getApiKey(requestParameters: GetApiKeyRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise { + const response = await this.getApiKeyRaw(requestParameters, initOverrides); + return await response.value(); + } + + /** + */ + async getApiKeysRaw(initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise>> { + const queryParameters: any = {}; + + const headerParameters: runtime.HTTPHeaders = {}; + + if (this.configuration && this.configuration.apiKey) { + headerParameters["x-api-key"] = this.configuration.apiKey("x-api-key"); // api_key authentication + } + + if (this.configuration && this.configuration.accessToken) { + const token = this.configuration.accessToken; + const tokenString = await token("bearer", []); + + if (tokenString) { + headerParameters["Authorization"] = `Bearer ${tokenString}`; + } + } + const response = await this.request({ + path: `/api-key`, + method: 'GET', + headers: headerParameters, + query: queryParameters, + }, initOverrides); + + return new runtime.JSONApiResponse(response, (jsonValue) => jsonValue.map(APIKeyResponseDtoFromJSON)); + } + + /** + */ + async getApiKeys(initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise> { + const response = await this.getApiKeysRaw(initOverrides); + return await response.value(); + } + + /** + */ + async updateApiKeyRaw(requestParameters: UpdateApiKeyRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise> { + if (requestParameters.id === null || requestParameters.id === undefined) { + throw new runtime.RequiredError('id','Required parameter requestParameters.id was null or undefined when calling updateApiKey.'); + } + + if (requestParameters.aPIKeyUpdateDto === null || requestParameters.aPIKeyUpdateDto === undefined) { + throw new runtime.RequiredError('aPIKeyUpdateDto','Required parameter requestParameters.aPIKeyUpdateDto was null or undefined when calling updateApiKey.'); + } + + const queryParameters: any = {}; + + const headerParameters: runtime.HTTPHeaders = {}; + + headerParameters['Content-Type'] = 'application/json'; + + if (this.configuration && this.configuration.apiKey) { + headerParameters["x-api-key"] = this.configuration.apiKey("x-api-key"); // api_key authentication + } + + if (this.configuration && this.configuration.accessToken) { + const token = this.configuration.accessToken; + const tokenString = await token("bearer", []); + + if (tokenString) { + headerParameters["Authorization"] = `Bearer ${tokenString}`; + } + } + const response = await this.request({ + path: `/api-key/{id}`.replace(`{${"id"}}`, encodeURIComponent(String(requestParameters.id))), + method: 'PUT', + headers: headerParameters, + query: queryParameters, + body: APIKeyUpdateDtoToJSON(requestParameters.aPIKeyUpdateDto), + }, initOverrides); + + return new runtime.JSONApiResponse(response, (jsonValue) => APIKeyResponseDtoFromJSON(jsonValue)); + } + + /** + */ + async updateApiKey(requestParameters: UpdateApiKeyRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise { + const response = await this.updateApiKeyRaw(requestParameters, initOverrides); + return await response.value(); + } + +} diff --git a/open-api/typescript-sdk/fetch-client/apis/ActivityApi.ts b/open-api/typescript-sdk/fetch-client/apis/ActivityApi.ts new file mode 100644 index 0000000000..321f58ca9c --- /dev/null +++ b/open-api/typescript-sdk/fetch-client/apis/ActivityApi.ts @@ -0,0 +1,253 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * Immich + * Immich API + * + * The version of the OpenAPI document: 1.94.1 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + + +import * as runtime from '../runtime'; +import type { + ActivityCreateDto, + ActivityResponseDto, + ActivityStatisticsResponseDto, + ReactionLevel, + ReactionType, +} from '../models/index'; +import { + ActivityCreateDtoFromJSON, + ActivityCreateDtoToJSON, + ActivityResponseDtoFromJSON, + ActivityResponseDtoToJSON, + ActivityStatisticsResponseDtoFromJSON, + ActivityStatisticsResponseDtoToJSON, + ReactionLevelFromJSON, + ReactionLevelToJSON, + ReactionTypeFromJSON, + ReactionTypeToJSON, +} from '../models/index'; + +export interface CreateActivityRequest { + activityCreateDto: ActivityCreateDto; +} + +export interface DeleteActivityRequest { + id: string; +} + +export interface GetActivitiesRequest { + albumId: string; + assetId?: string; + level?: ReactionLevel; + type?: ReactionType; + userId?: string; +} + +export interface GetActivityStatisticsRequest { + albumId: string; + assetId?: string; +} + +/** + * + */ +export class ActivityApi extends runtime.BaseAPI { + + /** + */ + async createActivityRaw(requestParameters: CreateActivityRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise> { + if (requestParameters.activityCreateDto === null || requestParameters.activityCreateDto === undefined) { + throw new runtime.RequiredError('activityCreateDto','Required parameter requestParameters.activityCreateDto was null or undefined when calling createActivity.'); + } + + const queryParameters: any = {}; + + const headerParameters: runtime.HTTPHeaders = {}; + + headerParameters['Content-Type'] = 'application/json'; + + if (this.configuration && this.configuration.apiKey) { + headerParameters["x-api-key"] = this.configuration.apiKey("x-api-key"); // api_key authentication + } + + if (this.configuration && this.configuration.accessToken) { + const token = this.configuration.accessToken; + const tokenString = await token("bearer", []); + + if (tokenString) { + headerParameters["Authorization"] = `Bearer ${tokenString}`; + } + } + const response = await this.request({ + path: `/activity`, + method: 'POST', + headers: headerParameters, + query: queryParameters, + body: ActivityCreateDtoToJSON(requestParameters.activityCreateDto), + }, initOverrides); + + return new runtime.JSONApiResponse(response, (jsonValue) => ActivityResponseDtoFromJSON(jsonValue)); + } + + /** + */ + async createActivity(requestParameters: CreateActivityRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise { + const response = await this.createActivityRaw(requestParameters, initOverrides); + return await response.value(); + } + + /** + */ + async deleteActivityRaw(requestParameters: DeleteActivityRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise> { + if (requestParameters.id === null || requestParameters.id === undefined) { + throw new runtime.RequiredError('id','Required parameter requestParameters.id was null or undefined when calling deleteActivity.'); + } + + const queryParameters: any = {}; + + const headerParameters: runtime.HTTPHeaders = {}; + + if (this.configuration && this.configuration.apiKey) { + headerParameters["x-api-key"] = this.configuration.apiKey("x-api-key"); // api_key authentication + } + + if (this.configuration && this.configuration.accessToken) { + const token = this.configuration.accessToken; + const tokenString = await token("bearer", []); + + if (tokenString) { + headerParameters["Authorization"] = `Bearer ${tokenString}`; + } + } + const response = await this.request({ + path: `/activity/{id}`.replace(`{${"id"}}`, encodeURIComponent(String(requestParameters.id))), + method: 'DELETE', + headers: headerParameters, + query: queryParameters, + }, initOverrides); + + return new runtime.VoidApiResponse(response); + } + + /** + */ + async deleteActivity(requestParameters: DeleteActivityRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise { + await this.deleteActivityRaw(requestParameters, initOverrides); + } + + /** + */ + async getActivitiesRaw(requestParameters: GetActivitiesRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise>> { + if (requestParameters.albumId === null || requestParameters.albumId === undefined) { + throw new runtime.RequiredError('albumId','Required parameter requestParameters.albumId was null or undefined when calling getActivities.'); + } + + const queryParameters: any = {}; + + if (requestParameters.albumId !== undefined) { + queryParameters['albumId'] = requestParameters.albumId; + } + + if (requestParameters.assetId !== undefined) { + queryParameters['assetId'] = requestParameters.assetId; + } + + if (requestParameters.level !== undefined) { + queryParameters['level'] = requestParameters.level; + } + + if (requestParameters.type !== undefined) { + queryParameters['type'] = requestParameters.type; + } + + if (requestParameters.userId !== undefined) { + queryParameters['userId'] = requestParameters.userId; + } + + const headerParameters: runtime.HTTPHeaders = {}; + + if (this.configuration && this.configuration.apiKey) { + headerParameters["x-api-key"] = this.configuration.apiKey("x-api-key"); // api_key authentication + } + + if (this.configuration && this.configuration.accessToken) { + const token = this.configuration.accessToken; + const tokenString = await token("bearer", []); + + if (tokenString) { + headerParameters["Authorization"] = `Bearer ${tokenString}`; + } + } + const response = await this.request({ + path: `/activity`, + method: 'GET', + headers: headerParameters, + query: queryParameters, + }, initOverrides); + + return new runtime.JSONApiResponse(response, (jsonValue) => jsonValue.map(ActivityResponseDtoFromJSON)); + } + + /** + */ + async getActivities(requestParameters: GetActivitiesRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise> { + const response = await this.getActivitiesRaw(requestParameters, initOverrides); + return await response.value(); + } + + /** + */ + async getActivityStatisticsRaw(requestParameters: GetActivityStatisticsRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise> { + if (requestParameters.albumId === null || requestParameters.albumId === undefined) { + throw new runtime.RequiredError('albumId','Required parameter requestParameters.albumId was null or undefined when calling getActivityStatistics.'); + } + + const queryParameters: any = {}; + + if (requestParameters.albumId !== undefined) { + queryParameters['albumId'] = requestParameters.albumId; + } + + if (requestParameters.assetId !== undefined) { + queryParameters['assetId'] = requestParameters.assetId; + } + + const headerParameters: runtime.HTTPHeaders = {}; + + if (this.configuration && this.configuration.apiKey) { + headerParameters["x-api-key"] = this.configuration.apiKey("x-api-key"); // api_key authentication + } + + if (this.configuration && this.configuration.accessToken) { + const token = this.configuration.accessToken; + const tokenString = await token("bearer", []); + + if (tokenString) { + headerParameters["Authorization"] = `Bearer ${tokenString}`; + } + } + const response = await this.request({ + path: `/activity/statistics`, + method: 'GET', + headers: headerParameters, + query: queryParameters, + }, initOverrides); + + return new runtime.JSONApiResponse(response, (jsonValue) => ActivityStatisticsResponseDtoFromJSON(jsonValue)); + } + + /** + */ + async getActivityStatistics(requestParameters: GetActivityStatisticsRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise { + const response = await this.getActivityStatisticsRaw(requestParameters, initOverrides); + return await response.value(); + } + +} diff --git a/open-api/typescript-sdk/fetch-client/apis/AlbumApi.ts b/open-api/typescript-sdk/fetch-client/apis/AlbumApi.ts new file mode 100644 index 0000000000..de5b88f716 --- /dev/null +++ b/open-api/typescript-sdk/fetch-client/apis/AlbumApi.ts @@ -0,0 +1,538 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * Immich + * Immich API + * + * The version of the OpenAPI document: 1.94.1 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + + +import * as runtime from '../runtime'; +import type { + AddUsersDto, + AlbumCountResponseDto, + AlbumResponseDto, + BulkIdResponseDto, + BulkIdsDto, + CreateAlbumDto, + UpdateAlbumDto, +} from '../models/index'; +import { + AddUsersDtoFromJSON, + AddUsersDtoToJSON, + AlbumCountResponseDtoFromJSON, + AlbumCountResponseDtoToJSON, + AlbumResponseDtoFromJSON, + AlbumResponseDtoToJSON, + BulkIdResponseDtoFromJSON, + BulkIdResponseDtoToJSON, + BulkIdsDtoFromJSON, + BulkIdsDtoToJSON, + CreateAlbumDtoFromJSON, + CreateAlbumDtoToJSON, + UpdateAlbumDtoFromJSON, + UpdateAlbumDtoToJSON, +} from '../models/index'; + +export interface AddAssetsToAlbumRequest { + id: string; + bulkIdsDto: BulkIdsDto; + key?: string; +} + +export interface AddUsersToAlbumRequest { + id: string; + addUsersDto: AddUsersDto; +} + +export interface CreateAlbumRequest { + createAlbumDto: CreateAlbumDto; +} + +export interface DeleteAlbumRequest { + id: string; +} + +export interface GetAlbumInfoRequest { + id: string; + key?: string; + withoutAssets?: boolean; +} + +export interface GetAllAlbumsRequest { + assetId?: string; + shared?: boolean; +} + +export interface RemoveAssetFromAlbumRequest { + id: string; + bulkIdsDto: BulkIdsDto; +} + +export interface RemoveUserFromAlbumRequest { + id: string; + userId: string; +} + +export interface UpdateAlbumInfoRequest { + id: string; + updateAlbumDto: UpdateAlbumDto; +} + +/** + * + */ +export class AlbumApi extends runtime.BaseAPI { + + /** + */ + async addAssetsToAlbumRaw(requestParameters: AddAssetsToAlbumRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise>> { + if (requestParameters.id === null || requestParameters.id === undefined) { + throw new runtime.RequiredError('id','Required parameter requestParameters.id was null or undefined when calling addAssetsToAlbum.'); + } + + if (requestParameters.bulkIdsDto === null || requestParameters.bulkIdsDto === undefined) { + throw new runtime.RequiredError('bulkIdsDto','Required parameter requestParameters.bulkIdsDto was null or undefined when calling addAssetsToAlbum.'); + } + + const queryParameters: any = {}; + + if (requestParameters.key !== undefined) { + queryParameters['key'] = requestParameters.key; + } + + const headerParameters: runtime.HTTPHeaders = {}; + + headerParameters['Content-Type'] = 'application/json'; + + if (this.configuration && this.configuration.apiKey) { + headerParameters["x-api-key"] = this.configuration.apiKey("x-api-key"); // api_key authentication + } + + if (this.configuration && this.configuration.accessToken) { + const token = this.configuration.accessToken; + const tokenString = await token("bearer", []); + + if (tokenString) { + headerParameters["Authorization"] = `Bearer ${tokenString}`; + } + } + const response = await this.request({ + path: `/album/{id}/assets`.replace(`{${"id"}}`, encodeURIComponent(String(requestParameters.id))), + method: 'PUT', + headers: headerParameters, + query: queryParameters, + body: BulkIdsDtoToJSON(requestParameters.bulkIdsDto), + }, initOverrides); + + return new runtime.JSONApiResponse(response, (jsonValue) => jsonValue.map(BulkIdResponseDtoFromJSON)); + } + + /** + */ + async addAssetsToAlbum(requestParameters: AddAssetsToAlbumRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise> { + const response = await this.addAssetsToAlbumRaw(requestParameters, initOverrides); + return await response.value(); + } + + /** + */ + async addUsersToAlbumRaw(requestParameters: AddUsersToAlbumRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise> { + if (requestParameters.id === null || requestParameters.id === undefined) { + throw new runtime.RequiredError('id','Required parameter requestParameters.id was null or undefined when calling addUsersToAlbum.'); + } + + if (requestParameters.addUsersDto === null || requestParameters.addUsersDto === undefined) { + throw new runtime.RequiredError('addUsersDto','Required parameter requestParameters.addUsersDto was null or undefined when calling addUsersToAlbum.'); + } + + const queryParameters: any = {}; + + const headerParameters: runtime.HTTPHeaders = {}; + + headerParameters['Content-Type'] = 'application/json'; + + if (this.configuration && this.configuration.apiKey) { + headerParameters["x-api-key"] = this.configuration.apiKey("x-api-key"); // api_key authentication + } + + if (this.configuration && this.configuration.accessToken) { + const token = this.configuration.accessToken; + const tokenString = await token("bearer", []); + + if (tokenString) { + headerParameters["Authorization"] = `Bearer ${tokenString}`; + } + } + const response = await this.request({ + path: `/album/{id}/users`.replace(`{${"id"}}`, encodeURIComponent(String(requestParameters.id))), + method: 'PUT', + headers: headerParameters, + query: queryParameters, + body: AddUsersDtoToJSON(requestParameters.addUsersDto), + }, initOverrides); + + return new runtime.JSONApiResponse(response, (jsonValue) => AlbumResponseDtoFromJSON(jsonValue)); + } + + /** + */ + async addUsersToAlbum(requestParameters: AddUsersToAlbumRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise { + const response = await this.addUsersToAlbumRaw(requestParameters, initOverrides); + return await response.value(); + } + + /** + */ + async createAlbumRaw(requestParameters: CreateAlbumRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise> { + if (requestParameters.createAlbumDto === null || requestParameters.createAlbumDto === undefined) { + throw new runtime.RequiredError('createAlbumDto','Required parameter requestParameters.createAlbumDto was null or undefined when calling createAlbum.'); + } + + const queryParameters: any = {}; + + const headerParameters: runtime.HTTPHeaders = {}; + + headerParameters['Content-Type'] = 'application/json'; + + if (this.configuration && this.configuration.apiKey) { + headerParameters["x-api-key"] = this.configuration.apiKey("x-api-key"); // api_key authentication + } + + if (this.configuration && this.configuration.accessToken) { + const token = this.configuration.accessToken; + const tokenString = await token("bearer", []); + + if (tokenString) { + headerParameters["Authorization"] = `Bearer ${tokenString}`; + } + } + const response = await this.request({ + path: `/album`, + method: 'POST', + headers: headerParameters, + query: queryParameters, + body: CreateAlbumDtoToJSON(requestParameters.createAlbumDto), + }, initOverrides); + + return new runtime.JSONApiResponse(response, (jsonValue) => AlbumResponseDtoFromJSON(jsonValue)); + } + + /** + */ + async createAlbum(requestParameters: CreateAlbumRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise { + const response = await this.createAlbumRaw(requestParameters, initOverrides); + return await response.value(); + } + + /** + */ + async deleteAlbumRaw(requestParameters: DeleteAlbumRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise> { + if (requestParameters.id === null || requestParameters.id === undefined) { + throw new runtime.RequiredError('id','Required parameter requestParameters.id was null or undefined when calling deleteAlbum.'); + } + + const queryParameters: any = {}; + + const headerParameters: runtime.HTTPHeaders = {}; + + if (this.configuration && this.configuration.apiKey) { + headerParameters["x-api-key"] = this.configuration.apiKey("x-api-key"); // api_key authentication + } + + if (this.configuration && this.configuration.accessToken) { + const token = this.configuration.accessToken; + const tokenString = await token("bearer", []); + + if (tokenString) { + headerParameters["Authorization"] = `Bearer ${tokenString}`; + } + } + const response = await this.request({ + path: `/album/{id}`.replace(`{${"id"}}`, encodeURIComponent(String(requestParameters.id))), + method: 'DELETE', + headers: headerParameters, + query: queryParameters, + }, initOverrides); + + return new runtime.VoidApiResponse(response); + } + + /** + */ + async deleteAlbum(requestParameters: DeleteAlbumRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise { + await this.deleteAlbumRaw(requestParameters, initOverrides); + } + + /** + */ + async getAlbumCountRaw(initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise> { + const queryParameters: any = {}; + + const headerParameters: runtime.HTTPHeaders = {}; + + if (this.configuration && this.configuration.apiKey) { + headerParameters["x-api-key"] = this.configuration.apiKey("x-api-key"); // api_key authentication + } + + if (this.configuration && this.configuration.accessToken) { + const token = this.configuration.accessToken; + const tokenString = await token("bearer", []); + + if (tokenString) { + headerParameters["Authorization"] = `Bearer ${tokenString}`; + } + } + const response = await this.request({ + path: `/album/count`, + method: 'GET', + headers: headerParameters, + query: queryParameters, + }, initOverrides); + + return new runtime.JSONApiResponse(response, (jsonValue) => AlbumCountResponseDtoFromJSON(jsonValue)); + } + + /** + */ + async getAlbumCount(initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise { + const response = await this.getAlbumCountRaw(initOverrides); + return await response.value(); + } + + /** + */ + async getAlbumInfoRaw(requestParameters: GetAlbumInfoRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise> { + if (requestParameters.id === null || requestParameters.id === undefined) { + throw new runtime.RequiredError('id','Required parameter requestParameters.id was null or undefined when calling getAlbumInfo.'); + } + + const queryParameters: any = {}; + + if (requestParameters.key !== undefined) { + queryParameters['key'] = requestParameters.key; + } + + if (requestParameters.withoutAssets !== undefined) { + queryParameters['withoutAssets'] = requestParameters.withoutAssets; + } + + const headerParameters: runtime.HTTPHeaders = {}; + + if (this.configuration && this.configuration.apiKey) { + headerParameters["x-api-key"] = this.configuration.apiKey("x-api-key"); // api_key authentication + } + + if (this.configuration && this.configuration.accessToken) { + const token = this.configuration.accessToken; + const tokenString = await token("bearer", []); + + if (tokenString) { + headerParameters["Authorization"] = `Bearer ${tokenString}`; + } + } + const response = await this.request({ + path: `/album/{id}`.replace(`{${"id"}}`, encodeURIComponent(String(requestParameters.id))), + method: 'GET', + headers: headerParameters, + query: queryParameters, + }, initOverrides); + + return new runtime.JSONApiResponse(response, (jsonValue) => AlbumResponseDtoFromJSON(jsonValue)); + } + + /** + */ + async getAlbumInfo(requestParameters: GetAlbumInfoRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise { + const response = await this.getAlbumInfoRaw(requestParameters, initOverrides); + return await response.value(); + } + + /** + */ + async getAllAlbumsRaw(requestParameters: GetAllAlbumsRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise>> { + const queryParameters: any = {}; + + if (requestParameters.assetId !== undefined) { + queryParameters['assetId'] = requestParameters.assetId; + } + + if (requestParameters.shared !== undefined) { + queryParameters['shared'] = requestParameters.shared; + } + + const headerParameters: runtime.HTTPHeaders = {}; + + if (this.configuration && this.configuration.apiKey) { + headerParameters["x-api-key"] = this.configuration.apiKey("x-api-key"); // api_key authentication + } + + if (this.configuration && this.configuration.accessToken) { + const token = this.configuration.accessToken; + const tokenString = await token("bearer", []); + + if (tokenString) { + headerParameters["Authorization"] = `Bearer ${tokenString}`; + } + } + const response = await this.request({ + path: `/album`, + method: 'GET', + headers: headerParameters, + query: queryParameters, + }, initOverrides); + + return new runtime.JSONApiResponse(response, (jsonValue) => jsonValue.map(AlbumResponseDtoFromJSON)); + } + + /** + */ + async getAllAlbums(requestParameters: GetAllAlbumsRequest = {}, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise> { + const response = await this.getAllAlbumsRaw(requestParameters, initOverrides); + return await response.value(); + } + + /** + */ + async removeAssetFromAlbumRaw(requestParameters: RemoveAssetFromAlbumRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise>> { + if (requestParameters.id === null || requestParameters.id === undefined) { + throw new runtime.RequiredError('id','Required parameter requestParameters.id was null or undefined when calling removeAssetFromAlbum.'); + } + + if (requestParameters.bulkIdsDto === null || requestParameters.bulkIdsDto === undefined) { + throw new runtime.RequiredError('bulkIdsDto','Required parameter requestParameters.bulkIdsDto was null or undefined when calling removeAssetFromAlbum.'); + } + + const queryParameters: any = {}; + + const headerParameters: runtime.HTTPHeaders = {}; + + headerParameters['Content-Type'] = 'application/json'; + + if (this.configuration && this.configuration.apiKey) { + headerParameters["x-api-key"] = this.configuration.apiKey("x-api-key"); // api_key authentication + } + + if (this.configuration && this.configuration.accessToken) { + const token = this.configuration.accessToken; + const tokenString = await token("bearer", []); + + if (tokenString) { + headerParameters["Authorization"] = `Bearer ${tokenString}`; + } + } + const response = await this.request({ + path: `/album/{id}/assets`.replace(`{${"id"}}`, encodeURIComponent(String(requestParameters.id))), + method: 'DELETE', + headers: headerParameters, + query: queryParameters, + body: BulkIdsDtoToJSON(requestParameters.bulkIdsDto), + }, initOverrides); + + return new runtime.JSONApiResponse(response, (jsonValue) => jsonValue.map(BulkIdResponseDtoFromJSON)); + } + + /** + */ + async removeAssetFromAlbum(requestParameters: RemoveAssetFromAlbumRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise> { + const response = await this.removeAssetFromAlbumRaw(requestParameters, initOverrides); + return await response.value(); + } + + /** + */ + async removeUserFromAlbumRaw(requestParameters: RemoveUserFromAlbumRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise> { + if (requestParameters.id === null || requestParameters.id === undefined) { + throw new runtime.RequiredError('id','Required parameter requestParameters.id was null or undefined when calling removeUserFromAlbum.'); + } + + if (requestParameters.userId === null || requestParameters.userId === undefined) { + throw new runtime.RequiredError('userId','Required parameter requestParameters.userId was null or undefined when calling removeUserFromAlbum.'); + } + + const queryParameters: any = {}; + + const headerParameters: runtime.HTTPHeaders = {}; + + if (this.configuration && this.configuration.apiKey) { + headerParameters["x-api-key"] = this.configuration.apiKey("x-api-key"); // api_key authentication + } + + if (this.configuration && this.configuration.accessToken) { + const token = this.configuration.accessToken; + const tokenString = await token("bearer", []); + + if (tokenString) { + headerParameters["Authorization"] = `Bearer ${tokenString}`; + } + } + const response = await this.request({ + path: `/album/{id}/user/{userId}`.replace(`{${"id"}}`, encodeURIComponent(String(requestParameters.id))).replace(`{${"userId"}}`, encodeURIComponent(String(requestParameters.userId))), + method: 'DELETE', + headers: headerParameters, + query: queryParameters, + }, initOverrides); + + return new runtime.VoidApiResponse(response); + } + + /** + */ + async removeUserFromAlbum(requestParameters: RemoveUserFromAlbumRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise { + await this.removeUserFromAlbumRaw(requestParameters, initOverrides); + } + + /** + */ + async updateAlbumInfoRaw(requestParameters: UpdateAlbumInfoRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise> { + if (requestParameters.id === null || requestParameters.id === undefined) { + throw new runtime.RequiredError('id','Required parameter requestParameters.id was null or undefined when calling updateAlbumInfo.'); + } + + if (requestParameters.updateAlbumDto === null || requestParameters.updateAlbumDto === undefined) { + throw new runtime.RequiredError('updateAlbumDto','Required parameter requestParameters.updateAlbumDto was null or undefined when calling updateAlbumInfo.'); + } + + const queryParameters: any = {}; + + const headerParameters: runtime.HTTPHeaders = {}; + + headerParameters['Content-Type'] = 'application/json'; + + if (this.configuration && this.configuration.apiKey) { + headerParameters["x-api-key"] = this.configuration.apiKey("x-api-key"); // api_key authentication + } + + if (this.configuration && this.configuration.accessToken) { + const token = this.configuration.accessToken; + const tokenString = await token("bearer", []); + + if (tokenString) { + headerParameters["Authorization"] = `Bearer ${tokenString}`; + } + } + const response = await this.request({ + path: `/album/{id}`.replace(`{${"id"}}`, encodeURIComponent(String(requestParameters.id))), + method: 'PATCH', + headers: headerParameters, + query: queryParameters, + body: UpdateAlbumDtoToJSON(requestParameters.updateAlbumDto), + }, initOverrides); + + return new runtime.JSONApiResponse(response, (jsonValue) => AlbumResponseDtoFromJSON(jsonValue)); + } + + /** + */ + async updateAlbumInfo(requestParameters: UpdateAlbumInfoRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise { + const response = await this.updateAlbumInfoRaw(requestParameters, initOverrides); + return await response.value(); + } + +} diff --git a/open-api/typescript-sdk/fetch-client/apis/AssetApi.ts b/open-api/typescript-sdk/fetch-client/apis/AssetApi.ts new file mode 100644 index 0000000000..5d5ea1b170 --- /dev/null +++ b/open-api/typescript-sdk/fetch-client/apis/AssetApi.ts @@ -0,0 +1,1963 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * Immich + * Immich API + * + * The version of the OpenAPI document: 1.94.1 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + + +import * as runtime from '../runtime'; +import type { + AssetBulkDeleteDto, + AssetBulkUpdateDto, + AssetBulkUploadCheckDto, + AssetBulkUploadCheckResponseDto, + AssetFileUploadResponseDto, + AssetIdsDto, + AssetJobsDto, + AssetOrder, + AssetResponseDto, + AssetStatsResponseDto, + AssetTypeEnum, + BulkIdsDto, + CheckExistingAssetsDto, + CheckExistingAssetsResponseDto, + CuratedLocationsResponseDto, + CuratedObjectsResponseDto, + DownloadInfoDto, + DownloadResponseDto, + MapMarkerResponseDto, + MemoryLaneResponseDto, + ThumbnailFormat, + TimeBucketResponseDto, + TimeBucketSize, + UpdateAssetDto, + UpdateStackParentDto, +} from '../models/index'; +import { + AssetBulkDeleteDtoFromJSON, + AssetBulkDeleteDtoToJSON, + AssetBulkUpdateDtoFromJSON, + AssetBulkUpdateDtoToJSON, + AssetBulkUploadCheckDtoFromJSON, + AssetBulkUploadCheckDtoToJSON, + AssetBulkUploadCheckResponseDtoFromJSON, + AssetBulkUploadCheckResponseDtoToJSON, + AssetFileUploadResponseDtoFromJSON, + AssetFileUploadResponseDtoToJSON, + AssetIdsDtoFromJSON, + AssetIdsDtoToJSON, + AssetJobsDtoFromJSON, + AssetJobsDtoToJSON, + AssetOrderFromJSON, + AssetOrderToJSON, + AssetResponseDtoFromJSON, + AssetResponseDtoToJSON, + AssetStatsResponseDtoFromJSON, + AssetStatsResponseDtoToJSON, + AssetTypeEnumFromJSON, + AssetTypeEnumToJSON, + BulkIdsDtoFromJSON, + BulkIdsDtoToJSON, + CheckExistingAssetsDtoFromJSON, + CheckExistingAssetsDtoToJSON, + CheckExistingAssetsResponseDtoFromJSON, + CheckExistingAssetsResponseDtoToJSON, + CuratedLocationsResponseDtoFromJSON, + CuratedLocationsResponseDtoToJSON, + CuratedObjectsResponseDtoFromJSON, + CuratedObjectsResponseDtoToJSON, + DownloadInfoDtoFromJSON, + DownloadInfoDtoToJSON, + DownloadResponseDtoFromJSON, + DownloadResponseDtoToJSON, + MapMarkerResponseDtoFromJSON, + MapMarkerResponseDtoToJSON, + MemoryLaneResponseDtoFromJSON, + MemoryLaneResponseDtoToJSON, + ThumbnailFormatFromJSON, + ThumbnailFormatToJSON, + TimeBucketResponseDtoFromJSON, + TimeBucketResponseDtoToJSON, + TimeBucketSizeFromJSON, + TimeBucketSizeToJSON, + UpdateAssetDtoFromJSON, + UpdateAssetDtoToJSON, + UpdateStackParentDtoFromJSON, + UpdateStackParentDtoToJSON, +} from '../models/index'; + +export interface CheckBulkUploadRequest { + assetBulkUploadCheckDto: AssetBulkUploadCheckDto; +} + +export interface CheckExistingAssetsRequest { + checkExistingAssetsDto: CheckExistingAssetsDto; +} + +export interface DeleteAssetsRequest { + assetBulkDeleteDto: AssetBulkDeleteDto; +} + +export interface DownloadArchiveOldRequest { + assetIdsDto: AssetIdsDto; + key?: string; +} + +export interface DownloadFileOldRequest { + id: string; + key?: string; +} + +export interface GetAllAssetsRequest { + ifNoneMatch?: string; + isArchived?: boolean; + isFavorite?: boolean; + skip?: number; + take?: number; + updatedAfter?: Date; + updatedBefore?: Date; + userId?: string; +} + +export interface GetAllUserAssetsByDeviceIdRequest { + deviceId: string; +} + +export interface GetAssetByIdRequest { + id: string; + key?: string; +} + +export interface GetAssetInfoRequest { + id: string; + key?: string; +} + +export interface GetAssetStatisticsRequest { + isArchived?: boolean; + isFavorite?: boolean; + isTrashed?: boolean; +} + +export interface GetAssetThumbnailRequest { + id: string; + format?: ThumbnailFormat; + key?: string; +} + +export interface GetDownloadInfoOldRequest { + downloadInfoDto: DownloadInfoDto; + key?: string; +} + +export interface GetMapMarkersRequest { + fileCreatedAfter?: Date; + fileCreatedBefore?: Date; + isArchived?: boolean; + isFavorite?: boolean; +} + +export interface GetMemoryLaneRequest { + day: number; + month: number; +} + +export interface GetRandomRequest { + count?: number; +} + +export interface GetTimeBucketRequest { + size: TimeBucketSize; + timeBucket: string; + albumId?: string; + isArchived?: boolean; + isFavorite?: boolean; + isTrashed?: boolean; + key?: string; + personId?: string; + userId?: string; + withPartners?: boolean; + withStacked?: boolean; +} + +export interface GetTimeBucketsRequest { + size: TimeBucketSize; + albumId?: string; + isArchived?: boolean; + isFavorite?: boolean; + isTrashed?: boolean; + key?: string; + personId?: string; + userId?: string; + withPartners?: boolean; + withStacked?: boolean; +} + +export interface RestoreAssetsOldRequest { + bulkIdsDto: BulkIdsDto; +} + +export interface RunAssetJobsRequest { + assetJobsDto: AssetJobsDto; +} + +export interface SearchAssetsRequest { + checksum?: string; + city?: string; + country?: string; + createdAfter?: Date; + createdBefore?: Date; + deviceAssetId?: string; + deviceId?: string; + encodedVideoPath?: string; + id?: string; + isArchived?: boolean; + isEncoded?: boolean; + isExternal?: boolean; + isFavorite?: boolean; + isMotion?: boolean; + isOffline?: boolean; + isReadOnly?: boolean; + isVisible?: boolean; + lensModel?: string; + libraryId?: string; + make?: string; + model?: string; + order?: AssetOrder; + originalFileName?: string; + originalPath?: string; + page?: number; + resizePath?: string; + size?: number; + state?: string; + takenAfter?: Date; + takenBefore?: Date; + trashedAfter?: Date; + trashedBefore?: Date; + type?: AssetTypeEnum; + updatedAfter?: Date; + updatedBefore?: Date; + webpPath?: string; + withDeleted?: boolean; + withExif?: boolean; + withPeople?: boolean; + withStacked?: boolean; +} + +export interface ServeFileRequest { + id: string; + isThumb?: boolean; + isWeb?: boolean; + key?: string; +} + +export interface UpdateAssetRequest { + id: string; + updateAssetDto: UpdateAssetDto; +} + +export interface UpdateAssetsRequest { + assetBulkUpdateDto: AssetBulkUpdateDto; +} + +export interface UpdateStackParentRequest { + updateStackParentDto: UpdateStackParentDto; +} + +export interface UploadFileRequest { + assetData: Blob; + deviceAssetId: string; + deviceId: string; + fileCreatedAt: Date; + fileModifiedAt: Date; + key?: string; + duration?: string; + isArchived?: boolean; + isExternal?: boolean; + isFavorite?: boolean; + isOffline?: boolean; + isReadOnly?: boolean; + isVisible?: boolean; + libraryId?: string; + livePhotoData?: Blob; + sidecarData?: Blob; +} + +/** + * + */ +export class AssetApi extends runtime.BaseAPI { + + /** + * Checks if assets exist by checksums + */ + async checkBulkUploadRaw(requestParameters: CheckBulkUploadRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise> { + if (requestParameters.assetBulkUploadCheckDto === null || requestParameters.assetBulkUploadCheckDto === undefined) { + throw new runtime.RequiredError('assetBulkUploadCheckDto','Required parameter requestParameters.assetBulkUploadCheckDto was null or undefined when calling checkBulkUpload.'); + } + + const queryParameters: any = {}; + + const headerParameters: runtime.HTTPHeaders = {}; + + headerParameters['Content-Type'] = 'application/json'; + + if (this.configuration && this.configuration.apiKey) { + headerParameters["x-api-key"] = this.configuration.apiKey("x-api-key"); // api_key authentication + } + + if (this.configuration && this.configuration.accessToken) { + const token = this.configuration.accessToken; + const tokenString = await token("bearer", []); + + if (tokenString) { + headerParameters["Authorization"] = `Bearer ${tokenString}`; + } + } + const response = await this.request({ + path: `/asset/bulk-upload-check`, + method: 'POST', + headers: headerParameters, + query: queryParameters, + body: AssetBulkUploadCheckDtoToJSON(requestParameters.assetBulkUploadCheckDto), + }, initOverrides); + + return new runtime.JSONApiResponse(response, (jsonValue) => AssetBulkUploadCheckResponseDtoFromJSON(jsonValue)); + } + + /** + * Checks if assets exist by checksums + */ + async checkBulkUpload(requestParameters: CheckBulkUploadRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise { + const response = await this.checkBulkUploadRaw(requestParameters, initOverrides); + return await response.value(); + } + + /** + * Checks if multiple assets exist on the server and returns all existing - used by background backup + */ + async checkExistingAssetsRaw(requestParameters: CheckExistingAssetsRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise> { + if (requestParameters.checkExistingAssetsDto === null || requestParameters.checkExistingAssetsDto === undefined) { + throw new runtime.RequiredError('checkExistingAssetsDto','Required parameter requestParameters.checkExistingAssetsDto was null or undefined when calling checkExistingAssets.'); + } + + const queryParameters: any = {}; + + const headerParameters: runtime.HTTPHeaders = {}; + + headerParameters['Content-Type'] = 'application/json'; + + if (this.configuration && this.configuration.apiKey) { + headerParameters["x-api-key"] = this.configuration.apiKey("x-api-key"); // api_key authentication + } + + if (this.configuration && this.configuration.accessToken) { + const token = this.configuration.accessToken; + const tokenString = await token("bearer", []); + + if (tokenString) { + headerParameters["Authorization"] = `Bearer ${tokenString}`; + } + } + const response = await this.request({ + path: `/asset/exist`, + method: 'POST', + headers: headerParameters, + query: queryParameters, + body: CheckExistingAssetsDtoToJSON(requestParameters.checkExistingAssetsDto), + }, initOverrides); + + return new runtime.JSONApiResponse(response, (jsonValue) => CheckExistingAssetsResponseDtoFromJSON(jsonValue)); + } + + /** + * Checks if multiple assets exist on the server and returns all existing - used by background backup + */ + async checkExistingAssets(requestParameters: CheckExistingAssetsRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise { + const response = await this.checkExistingAssetsRaw(requestParameters, initOverrides); + return await response.value(); + } + + /** + */ + async deleteAssetsRaw(requestParameters: DeleteAssetsRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise> { + if (requestParameters.assetBulkDeleteDto === null || requestParameters.assetBulkDeleteDto === undefined) { + throw new runtime.RequiredError('assetBulkDeleteDto','Required parameter requestParameters.assetBulkDeleteDto was null or undefined when calling deleteAssets.'); + } + + const queryParameters: any = {}; + + const headerParameters: runtime.HTTPHeaders = {}; + + headerParameters['Content-Type'] = 'application/json'; + + if (this.configuration && this.configuration.apiKey) { + headerParameters["x-api-key"] = this.configuration.apiKey("x-api-key"); // api_key authentication + } + + if (this.configuration && this.configuration.accessToken) { + const token = this.configuration.accessToken; + const tokenString = await token("bearer", []); + + if (tokenString) { + headerParameters["Authorization"] = `Bearer ${tokenString}`; + } + } + const response = await this.request({ + path: `/asset`, + method: 'DELETE', + headers: headerParameters, + query: queryParameters, + body: AssetBulkDeleteDtoToJSON(requestParameters.assetBulkDeleteDto), + }, initOverrides); + + return new runtime.VoidApiResponse(response); + } + + /** + */ + async deleteAssets(requestParameters: DeleteAssetsRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise { + await this.deleteAssetsRaw(requestParameters, initOverrides); + } + + /** + */ + async downloadArchiveOldRaw(requestParameters: DownloadArchiveOldRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise> { + if (requestParameters.assetIdsDto === null || requestParameters.assetIdsDto === undefined) { + throw new runtime.RequiredError('assetIdsDto','Required parameter requestParameters.assetIdsDto was null or undefined when calling downloadArchiveOld.'); + } + + const queryParameters: any = {}; + + if (requestParameters.key !== undefined) { + queryParameters['key'] = requestParameters.key; + } + + const headerParameters: runtime.HTTPHeaders = {}; + + headerParameters['Content-Type'] = 'application/json'; + + if (this.configuration && this.configuration.apiKey) { + headerParameters["x-api-key"] = this.configuration.apiKey("x-api-key"); // api_key authentication + } + + if (this.configuration && this.configuration.accessToken) { + const token = this.configuration.accessToken; + const tokenString = await token("bearer", []); + + if (tokenString) { + headerParameters["Authorization"] = `Bearer ${tokenString}`; + } + } + const response = await this.request({ + path: `/asset/download/archive`, + method: 'POST', + headers: headerParameters, + query: queryParameters, + body: AssetIdsDtoToJSON(requestParameters.assetIdsDto), + }, initOverrides); + + return new runtime.BlobApiResponse(response); + } + + /** + */ + async downloadArchiveOld(requestParameters: DownloadArchiveOldRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise { + const response = await this.downloadArchiveOldRaw(requestParameters, initOverrides); + return await response.value(); + } + + /** + */ + async downloadFileOldRaw(requestParameters: DownloadFileOldRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise> { + if (requestParameters.id === null || requestParameters.id === undefined) { + throw new runtime.RequiredError('id','Required parameter requestParameters.id was null or undefined when calling downloadFileOld.'); + } + + const queryParameters: any = {}; + + if (requestParameters.key !== undefined) { + queryParameters['key'] = requestParameters.key; + } + + const headerParameters: runtime.HTTPHeaders = {}; + + if (this.configuration && this.configuration.apiKey) { + headerParameters["x-api-key"] = this.configuration.apiKey("x-api-key"); // api_key authentication + } + + if (this.configuration && this.configuration.accessToken) { + const token = this.configuration.accessToken; + const tokenString = await token("bearer", []); + + if (tokenString) { + headerParameters["Authorization"] = `Bearer ${tokenString}`; + } + } + const response = await this.request({ + path: `/asset/download/{id}`.replace(`{${"id"}}`, encodeURIComponent(String(requestParameters.id))), + method: 'POST', + headers: headerParameters, + query: queryParameters, + }, initOverrides); + + return new runtime.BlobApiResponse(response); + } + + /** + */ + async downloadFileOld(requestParameters: DownloadFileOldRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise { + const response = await this.downloadFileOldRaw(requestParameters, initOverrides); + return await response.value(); + } + + /** + */ + async emptyTrashOldRaw(initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise> { + const queryParameters: any = {}; + + const headerParameters: runtime.HTTPHeaders = {}; + + if (this.configuration && this.configuration.apiKey) { + headerParameters["x-api-key"] = this.configuration.apiKey("x-api-key"); // api_key authentication + } + + if (this.configuration && this.configuration.accessToken) { + const token = this.configuration.accessToken; + const tokenString = await token("bearer", []); + + if (tokenString) { + headerParameters["Authorization"] = `Bearer ${tokenString}`; + } + } + const response = await this.request({ + path: `/asset/trash/empty`, + method: 'POST', + headers: headerParameters, + query: queryParameters, + }, initOverrides); + + return new runtime.VoidApiResponse(response); + } + + /** + */ + async emptyTrashOld(initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise { + await this.emptyTrashOldRaw(initOverrides); + } + + /** + * Get all AssetEntity belong to the user + */ + async getAllAssetsRaw(requestParameters: GetAllAssetsRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise>> { + const queryParameters: any = {}; + + if (requestParameters.isArchived !== undefined) { + queryParameters['isArchived'] = requestParameters.isArchived; + } + + if (requestParameters.isFavorite !== undefined) { + queryParameters['isFavorite'] = requestParameters.isFavorite; + } + + if (requestParameters.skip !== undefined) { + queryParameters['skip'] = requestParameters.skip; + } + + if (requestParameters.take !== undefined) { + queryParameters['take'] = requestParameters.take; + } + + if (requestParameters.updatedAfter !== undefined) { + queryParameters['updatedAfter'] = (requestParameters.updatedAfter as any).toISOString(); + } + + if (requestParameters.updatedBefore !== undefined) { + queryParameters['updatedBefore'] = (requestParameters.updatedBefore as any).toISOString(); + } + + if (requestParameters.userId !== undefined) { + queryParameters['userId'] = requestParameters.userId; + } + + const headerParameters: runtime.HTTPHeaders = {}; + + if (requestParameters.ifNoneMatch !== undefined && requestParameters.ifNoneMatch !== null) { + headerParameters['if-none-match'] = String(requestParameters.ifNoneMatch); + } + + if (this.configuration && this.configuration.apiKey) { + headerParameters["x-api-key"] = this.configuration.apiKey("x-api-key"); // api_key authentication + } + + if (this.configuration && this.configuration.accessToken) { + const token = this.configuration.accessToken; + const tokenString = await token("bearer", []); + + if (tokenString) { + headerParameters["Authorization"] = `Bearer ${tokenString}`; + } + } + const response = await this.request({ + path: `/asset`, + method: 'GET', + headers: headerParameters, + query: queryParameters, + }, initOverrides); + + return new runtime.JSONApiResponse(response, (jsonValue) => jsonValue.map(AssetResponseDtoFromJSON)); + } + + /** + * Get all AssetEntity belong to the user + */ + async getAllAssets(requestParameters: GetAllAssetsRequest = {}, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise> { + const response = await this.getAllAssetsRaw(requestParameters, initOverrides); + return await response.value(); + } + + /** + * Get all asset of a device that are in the database, ID only. + */ + async getAllUserAssetsByDeviceIdRaw(requestParameters: GetAllUserAssetsByDeviceIdRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise>> { + if (requestParameters.deviceId === null || requestParameters.deviceId === undefined) { + throw new runtime.RequiredError('deviceId','Required parameter requestParameters.deviceId was null or undefined when calling getAllUserAssetsByDeviceId.'); + } + + const queryParameters: any = {}; + + const headerParameters: runtime.HTTPHeaders = {}; + + if (this.configuration && this.configuration.apiKey) { + headerParameters["x-api-key"] = this.configuration.apiKey("x-api-key"); // api_key authentication + } + + if (this.configuration && this.configuration.accessToken) { + const token = this.configuration.accessToken; + const tokenString = await token("bearer", []); + + if (tokenString) { + headerParameters["Authorization"] = `Bearer ${tokenString}`; + } + } + const response = await this.request({ + path: `/asset/device/{deviceId}`.replace(`{${"deviceId"}}`, encodeURIComponent(String(requestParameters.deviceId))), + method: 'GET', + headers: headerParameters, + query: queryParameters, + }, initOverrides); + + return new runtime.JSONApiResponse(response); + } + + /** + * Get all asset of a device that are in the database, ID only. + */ + async getAllUserAssetsByDeviceId(requestParameters: GetAllUserAssetsByDeviceIdRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise> { + const response = await this.getAllUserAssetsByDeviceIdRaw(requestParameters, initOverrides); + return await response.value(); + } + + /** + * Get a single asset\'s information + * @deprecated + */ + async getAssetByIdRaw(requestParameters: GetAssetByIdRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise> { + if (requestParameters.id === null || requestParameters.id === undefined) { + throw new runtime.RequiredError('id','Required parameter requestParameters.id was null or undefined when calling getAssetById.'); + } + + const queryParameters: any = {}; + + if (requestParameters.key !== undefined) { + queryParameters['key'] = requestParameters.key; + } + + const headerParameters: runtime.HTTPHeaders = {}; + + if (this.configuration && this.configuration.apiKey) { + headerParameters["x-api-key"] = this.configuration.apiKey("x-api-key"); // api_key authentication + } + + if (this.configuration && this.configuration.accessToken) { + const token = this.configuration.accessToken; + const tokenString = await token("bearer", []); + + if (tokenString) { + headerParameters["Authorization"] = `Bearer ${tokenString}`; + } + } + const response = await this.request({ + path: `/asset/assetById/{id}`.replace(`{${"id"}}`, encodeURIComponent(String(requestParameters.id))), + method: 'GET', + headers: headerParameters, + query: queryParameters, + }, initOverrides); + + return new runtime.JSONApiResponse(response, (jsonValue) => AssetResponseDtoFromJSON(jsonValue)); + } + + /** + * Get a single asset\'s information + * @deprecated + */ + async getAssetById(requestParameters: GetAssetByIdRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise { + const response = await this.getAssetByIdRaw(requestParameters, initOverrides); + return await response.value(); + } + + /** + */ + async getAssetInfoRaw(requestParameters: GetAssetInfoRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise> { + if (requestParameters.id === null || requestParameters.id === undefined) { + throw new runtime.RequiredError('id','Required parameter requestParameters.id was null or undefined when calling getAssetInfo.'); + } + + const queryParameters: any = {}; + + if (requestParameters.key !== undefined) { + queryParameters['key'] = requestParameters.key; + } + + const headerParameters: runtime.HTTPHeaders = {}; + + if (this.configuration && this.configuration.apiKey) { + headerParameters["x-api-key"] = this.configuration.apiKey("x-api-key"); // api_key authentication + } + + if (this.configuration && this.configuration.accessToken) { + const token = this.configuration.accessToken; + const tokenString = await token("bearer", []); + + if (tokenString) { + headerParameters["Authorization"] = `Bearer ${tokenString}`; + } + } + const response = await this.request({ + path: `/asset/{id}`.replace(`{${"id"}}`, encodeURIComponent(String(requestParameters.id))), + method: 'GET', + headers: headerParameters, + query: queryParameters, + }, initOverrides); + + return new runtime.JSONApiResponse(response, (jsonValue) => AssetResponseDtoFromJSON(jsonValue)); + } + + /** + */ + async getAssetInfo(requestParameters: GetAssetInfoRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise { + const response = await this.getAssetInfoRaw(requestParameters, initOverrides); + return await response.value(); + } + + /** + */ + async getAssetSearchTermsRaw(initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise>> { + const queryParameters: any = {}; + + const headerParameters: runtime.HTTPHeaders = {}; + + if (this.configuration && this.configuration.apiKey) { + headerParameters["x-api-key"] = this.configuration.apiKey("x-api-key"); // api_key authentication + } + + if (this.configuration && this.configuration.accessToken) { + const token = this.configuration.accessToken; + const tokenString = await token("bearer", []); + + if (tokenString) { + headerParameters["Authorization"] = `Bearer ${tokenString}`; + } + } + const response = await this.request({ + path: `/asset/search-terms`, + method: 'GET', + headers: headerParameters, + query: queryParameters, + }, initOverrides); + + return new runtime.JSONApiResponse(response); + } + + /** + */ + async getAssetSearchTerms(initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise> { + const response = await this.getAssetSearchTermsRaw(initOverrides); + return await response.value(); + } + + /** + */ + async getAssetStatisticsRaw(requestParameters: GetAssetStatisticsRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise> { + const queryParameters: any = {}; + + if (requestParameters.isArchived !== undefined) { + queryParameters['isArchived'] = requestParameters.isArchived; + } + + if (requestParameters.isFavorite !== undefined) { + queryParameters['isFavorite'] = requestParameters.isFavorite; + } + + if (requestParameters.isTrashed !== undefined) { + queryParameters['isTrashed'] = requestParameters.isTrashed; + } + + const headerParameters: runtime.HTTPHeaders = {}; + + if (this.configuration && this.configuration.apiKey) { + headerParameters["x-api-key"] = this.configuration.apiKey("x-api-key"); // api_key authentication + } + + if (this.configuration && this.configuration.accessToken) { + const token = this.configuration.accessToken; + const tokenString = await token("bearer", []); + + if (tokenString) { + headerParameters["Authorization"] = `Bearer ${tokenString}`; + } + } + const response = await this.request({ + path: `/asset/statistics`, + method: 'GET', + headers: headerParameters, + query: queryParameters, + }, initOverrides); + + return new runtime.JSONApiResponse(response, (jsonValue) => AssetStatsResponseDtoFromJSON(jsonValue)); + } + + /** + */ + async getAssetStatistics(requestParameters: GetAssetStatisticsRequest = {}, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise { + const response = await this.getAssetStatisticsRaw(requestParameters, initOverrides); + return await response.value(); + } + + /** + */ + async getAssetThumbnailRaw(requestParameters: GetAssetThumbnailRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise> { + if (requestParameters.id === null || requestParameters.id === undefined) { + throw new runtime.RequiredError('id','Required parameter requestParameters.id was null or undefined when calling getAssetThumbnail.'); + } + + const queryParameters: any = {}; + + if (requestParameters.format !== undefined) { + queryParameters['format'] = requestParameters.format; + } + + if (requestParameters.key !== undefined) { + queryParameters['key'] = requestParameters.key; + } + + const headerParameters: runtime.HTTPHeaders = {}; + + if (this.configuration && this.configuration.apiKey) { + headerParameters["x-api-key"] = this.configuration.apiKey("x-api-key"); // api_key authentication + } + + if (this.configuration && this.configuration.accessToken) { + const token = this.configuration.accessToken; + const tokenString = await token("bearer", []); + + if (tokenString) { + headerParameters["Authorization"] = `Bearer ${tokenString}`; + } + } + const response = await this.request({ + path: `/asset/thumbnail/{id}`.replace(`{${"id"}}`, encodeURIComponent(String(requestParameters.id))), + method: 'GET', + headers: headerParameters, + query: queryParameters, + }, initOverrides); + + return new runtime.BlobApiResponse(response); + } + + /** + */ + async getAssetThumbnail(requestParameters: GetAssetThumbnailRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise { + const response = await this.getAssetThumbnailRaw(requestParameters, initOverrides); + return await response.value(); + } + + /** + */ + async getCuratedLocationsRaw(initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise>> { + const queryParameters: any = {}; + + const headerParameters: runtime.HTTPHeaders = {}; + + if (this.configuration && this.configuration.apiKey) { + headerParameters["x-api-key"] = this.configuration.apiKey("x-api-key"); // api_key authentication + } + + if (this.configuration && this.configuration.accessToken) { + const token = this.configuration.accessToken; + const tokenString = await token("bearer", []); + + if (tokenString) { + headerParameters["Authorization"] = `Bearer ${tokenString}`; + } + } + const response = await this.request({ + path: `/asset/curated-locations`, + method: 'GET', + headers: headerParameters, + query: queryParameters, + }, initOverrides); + + return new runtime.JSONApiResponse(response, (jsonValue) => jsonValue.map(CuratedLocationsResponseDtoFromJSON)); + } + + /** + */ + async getCuratedLocations(initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise> { + const response = await this.getCuratedLocationsRaw(initOverrides); + return await response.value(); + } + + /** + */ + async getCuratedObjectsRaw(initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise>> { + const queryParameters: any = {}; + + const headerParameters: runtime.HTTPHeaders = {}; + + if (this.configuration && this.configuration.apiKey) { + headerParameters["x-api-key"] = this.configuration.apiKey("x-api-key"); // api_key authentication + } + + if (this.configuration && this.configuration.accessToken) { + const token = this.configuration.accessToken; + const tokenString = await token("bearer", []); + + if (tokenString) { + headerParameters["Authorization"] = `Bearer ${tokenString}`; + } + } + const response = await this.request({ + path: `/asset/curated-objects`, + method: 'GET', + headers: headerParameters, + query: queryParameters, + }, initOverrides); + + return new runtime.JSONApiResponse(response, (jsonValue) => jsonValue.map(CuratedObjectsResponseDtoFromJSON)); + } + + /** + */ + async getCuratedObjects(initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise> { + const response = await this.getCuratedObjectsRaw(initOverrides); + return await response.value(); + } + + /** + */ + async getDownloadInfoOldRaw(requestParameters: GetDownloadInfoOldRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise> { + if (requestParameters.downloadInfoDto === null || requestParameters.downloadInfoDto === undefined) { + throw new runtime.RequiredError('downloadInfoDto','Required parameter requestParameters.downloadInfoDto was null or undefined when calling getDownloadInfoOld.'); + } + + const queryParameters: any = {}; + + if (requestParameters.key !== undefined) { + queryParameters['key'] = requestParameters.key; + } + + const headerParameters: runtime.HTTPHeaders = {}; + + headerParameters['Content-Type'] = 'application/json'; + + if (this.configuration && this.configuration.apiKey) { + headerParameters["x-api-key"] = this.configuration.apiKey("x-api-key"); // api_key authentication + } + + if (this.configuration && this.configuration.accessToken) { + const token = this.configuration.accessToken; + const tokenString = await token("bearer", []); + + if (tokenString) { + headerParameters["Authorization"] = `Bearer ${tokenString}`; + } + } + const response = await this.request({ + path: `/asset/download/info`, + method: 'POST', + headers: headerParameters, + query: queryParameters, + body: DownloadInfoDtoToJSON(requestParameters.downloadInfoDto), + }, initOverrides); + + return new runtime.JSONApiResponse(response, (jsonValue) => DownloadResponseDtoFromJSON(jsonValue)); + } + + /** + */ + async getDownloadInfoOld(requestParameters: GetDownloadInfoOldRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise { + const response = await this.getDownloadInfoOldRaw(requestParameters, initOverrides); + return await response.value(); + } + + /** + */ + async getMapMarkersRaw(requestParameters: GetMapMarkersRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise>> { + const queryParameters: any = {}; + + if (requestParameters.fileCreatedAfter !== undefined) { + queryParameters['fileCreatedAfter'] = (requestParameters.fileCreatedAfter as any).toISOString(); + } + + if (requestParameters.fileCreatedBefore !== undefined) { + queryParameters['fileCreatedBefore'] = (requestParameters.fileCreatedBefore as any).toISOString(); + } + + if (requestParameters.isArchived !== undefined) { + queryParameters['isArchived'] = requestParameters.isArchived; + } + + if (requestParameters.isFavorite !== undefined) { + queryParameters['isFavorite'] = requestParameters.isFavorite; + } + + const headerParameters: runtime.HTTPHeaders = {}; + + if (this.configuration && this.configuration.apiKey) { + headerParameters["x-api-key"] = this.configuration.apiKey("x-api-key"); // api_key authentication + } + + if (this.configuration && this.configuration.accessToken) { + const token = this.configuration.accessToken; + const tokenString = await token("bearer", []); + + if (tokenString) { + headerParameters["Authorization"] = `Bearer ${tokenString}`; + } + } + const response = await this.request({ + path: `/asset/map-marker`, + method: 'GET', + headers: headerParameters, + query: queryParameters, + }, initOverrides); + + return new runtime.JSONApiResponse(response, (jsonValue) => jsonValue.map(MapMarkerResponseDtoFromJSON)); + } + + /** + */ + async getMapMarkers(requestParameters: GetMapMarkersRequest = {}, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise> { + const response = await this.getMapMarkersRaw(requestParameters, initOverrides); + return await response.value(); + } + + /** + */ + async getMemoryLaneRaw(requestParameters: GetMemoryLaneRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise>> { + if (requestParameters.day === null || requestParameters.day === undefined) { + throw new runtime.RequiredError('day','Required parameter requestParameters.day was null or undefined when calling getMemoryLane.'); + } + + if (requestParameters.month === null || requestParameters.month === undefined) { + throw new runtime.RequiredError('month','Required parameter requestParameters.month was null or undefined when calling getMemoryLane.'); + } + + const queryParameters: any = {}; + + if (requestParameters.day !== undefined) { + queryParameters['day'] = requestParameters.day; + } + + if (requestParameters.month !== undefined) { + queryParameters['month'] = requestParameters.month; + } + + const headerParameters: runtime.HTTPHeaders = {}; + + if (this.configuration && this.configuration.apiKey) { + headerParameters["x-api-key"] = this.configuration.apiKey("x-api-key"); // api_key authentication + } + + if (this.configuration && this.configuration.accessToken) { + const token = this.configuration.accessToken; + const tokenString = await token("bearer", []); + + if (tokenString) { + headerParameters["Authorization"] = `Bearer ${tokenString}`; + } + } + const response = await this.request({ + path: `/asset/memory-lane`, + method: 'GET', + headers: headerParameters, + query: queryParameters, + }, initOverrides); + + return new runtime.JSONApiResponse(response, (jsonValue) => jsonValue.map(MemoryLaneResponseDtoFromJSON)); + } + + /** + */ + async getMemoryLane(requestParameters: GetMemoryLaneRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise> { + const response = await this.getMemoryLaneRaw(requestParameters, initOverrides); + return await response.value(); + } + + /** + */ + async getRandomRaw(requestParameters: GetRandomRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise>> { + const queryParameters: any = {}; + + if (requestParameters.count !== undefined) { + queryParameters['count'] = requestParameters.count; + } + + const headerParameters: runtime.HTTPHeaders = {}; + + if (this.configuration && this.configuration.apiKey) { + headerParameters["x-api-key"] = this.configuration.apiKey("x-api-key"); // api_key authentication + } + + if (this.configuration && this.configuration.accessToken) { + const token = this.configuration.accessToken; + const tokenString = await token("bearer", []); + + if (tokenString) { + headerParameters["Authorization"] = `Bearer ${tokenString}`; + } + } + const response = await this.request({ + path: `/asset/random`, + method: 'GET', + headers: headerParameters, + query: queryParameters, + }, initOverrides); + + return new runtime.JSONApiResponse(response, (jsonValue) => jsonValue.map(AssetResponseDtoFromJSON)); + } + + /** + */ + async getRandom(requestParameters: GetRandomRequest = {}, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise> { + const response = await this.getRandomRaw(requestParameters, initOverrides); + return await response.value(); + } + + /** + */ + async getTimeBucketRaw(requestParameters: GetTimeBucketRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise>> { + if (requestParameters.size === null || requestParameters.size === undefined) { + throw new runtime.RequiredError('size','Required parameter requestParameters.size was null or undefined when calling getTimeBucket.'); + } + + if (requestParameters.timeBucket === null || requestParameters.timeBucket === undefined) { + throw new runtime.RequiredError('timeBucket','Required parameter requestParameters.timeBucket was null or undefined when calling getTimeBucket.'); + } + + const queryParameters: any = {}; + + if (requestParameters.albumId !== undefined) { + queryParameters['albumId'] = requestParameters.albumId; + } + + if (requestParameters.isArchived !== undefined) { + queryParameters['isArchived'] = requestParameters.isArchived; + } + + if (requestParameters.isFavorite !== undefined) { + queryParameters['isFavorite'] = requestParameters.isFavorite; + } + + if (requestParameters.isTrashed !== undefined) { + queryParameters['isTrashed'] = requestParameters.isTrashed; + } + + if (requestParameters.key !== undefined) { + queryParameters['key'] = requestParameters.key; + } + + if (requestParameters.personId !== undefined) { + queryParameters['personId'] = requestParameters.personId; + } + + if (requestParameters.size !== undefined) { + queryParameters['size'] = requestParameters.size; + } + + if (requestParameters.timeBucket !== undefined) { + queryParameters['timeBucket'] = requestParameters.timeBucket; + } + + if (requestParameters.userId !== undefined) { + queryParameters['userId'] = requestParameters.userId; + } + + if (requestParameters.withPartners !== undefined) { + queryParameters['withPartners'] = requestParameters.withPartners; + } + + if (requestParameters.withStacked !== undefined) { + queryParameters['withStacked'] = requestParameters.withStacked; + } + + const headerParameters: runtime.HTTPHeaders = {}; + + if (this.configuration && this.configuration.apiKey) { + headerParameters["x-api-key"] = this.configuration.apiKey("x-api-key"); // api_key authentication + } + + if (this.configuration && this.configuration.accessToken) { + const token = this.configuration.accessToken; + const tokenString = await token("bearer", []); + + if (tokenString) { + headerParameters["Authorization"] = `Bearer ${tokenString}`; + } + } + const response = await this.request({ + path: `/asset/time-bucket`, + method: 'GET', + headers: headerParameters, + query: queryParameters, + }, initOverrides); + + return new runtime.JSONApiResponse(response, (jsonValue) => jsonValue.map(AssetResponseDtoFromJSON)); + } + + /** + */ + async getTimeBucket(requestParameters: GetTimeBucketRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise> { + const response = await this.getTimeBucketRaw(requestParameters, initOverrides); + return await response.value(); + } + + /** + */ + async getTimeBucketsRaw(requestParameters: GetTimeBucketsRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise>> { + if (requestParameters.size === null || requestParameters.size === undefined) { + throw new runtime.RequiredError('size','Required parameter requestParameters.size was null or undefined when calling getTimeBuckets.'); + } + + const queryParameters: any = {}; + + if (requestParameters.albumId !== undefined) { + queryParameters['albumId'] = requestParameters.albumId; + } + + if (requestParameters.isArchived !== undefined) { + queryParameters['isArchived'] = requestParameters.isArchived; + } + + if (requestParameters.isFavorite !== undefined) { + queryParameters['isFavorite'] = requestParameters.isFavorite; + } + + if (requestParameters.isTrashed !== undefined) { + queryParameters['isTrashed'] = requestParameters.isTrashed; + } + + if (requestParameters.key !== undefined) { + queryParameters['key'] = requestParameters.key; + } + + if (requestParameters.personId !== undefined) { + queryParameters['personId'] = requestParameters.personId; + } + + if (requestParameters.size !== undefined) { + queryParameters['size'] = requestParameters.size; + } + + if (requestParameters.userId !== undefined) { + queryParameters['userId'] = requestParameters.userId; + } + + if (requestParameters.withPartners !== undefined) { + queryParameters['withPartners'] = requestParameters.withPartners; + } + + if (requestParameters.withStacked !== undefined) { + queryParameters['withStacked'] = requestParameters.withStacked; + } + + const headerParameters: runtime.HTTPHeaders = {}; + + if (this.configuration && this.configuration.apiKey) { + headerParameters["x-api-key"] = this.configuration.apiKey("x-api-key"); // api_key authentication + } + + if (this.configuration && this.configuration.accessToken) { + const token = this.configuration.accessToken; + const tokenString = await token("bearer", []); + + if (tokenString) { + headerParameters["Authorization"] = `Bearer ${tokenString}`; + } + } + const response = await this.request({ + path: `/asset/time-buckets`, + method: 'GET', + headers: headerParameters, + query: queryParameters, + }, initOverrides); + + return new runtime.JSONApiResponse(response, (jsonValue) => jsonValue.map(TimeBucketResponseDtoFromJSON)); + } + + /** + */ + async getTimeBuckets(requestParameters: GetTimeBucketsRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise> { + const response = await this.getTimeBucketsRaw(requestParameters, initOverrides); + return await response.value(); + } + + /** + */ + async restoreAssetsOldRaw(requestParameters: RestoreAssetsOldRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise> { + if (requestParameters.bulkIdsDto === null || requestParameters.bulkIdsDto === undefined) { + throw new runtime.RequiredError('bulkIdsDto','Required parameter requestParameters.bulkIdsDto was null or undefined when calling restoreAssetsOld.'); + } + + const queryParameters: any = {}; + + const headerParameters: runtime.HTTPHeaders = {}; + + headerParameters['Content-Type'] = 'application/json'; + + if (this.configuration && this.configuration.apiKey) { + headerParameters["x-api-key"] = this.configuration.apiKey("x-api-key"); // api_key authentication + } + + if (this.configuration && this.configuration.accessToken) { + const token = this.configuration.accessToken; + const tokenString = await token("bearer", []); + + if (tokenString) { + headerParameters["Authorization"] = `Bearer ${tokenString}`; + } + } + const response = await this.request({ + path: `/asset/restore`, + method: 'POST', + headers: headerParameters, + query: queryParameters, + body: BulkIdsDtoToJSON(requestParameters.bulkIdsDto), + }, initOverrides); + + return new runtime.VoidApiResponse(response); + } + + /** + */ + async restoreAssetsOld(requestParameters: RestoreAssetsOldRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise { + await this.restoreAssetsOldRaw(requestParameters, initOverrides); + } + + /** + */ + async restoreTrashOldRaw(initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise> { + const queryParameters: any = {}; + + const headerParameters: runtime.HTTPHeaders = {}; + + if (this.configuration && this.configuration.apiKey) { + headerParameters["x-api-key"] = this.configuration.apiKey("x-api-key"); // api_key authentication + } + + if (this.configuration && this.configuration.accessToken) { + const token = this.configuration.accessToken; + const tokenString = await token("bearer", []); + + if (tokenString) { + headerParameters["Authorization"] = `Bearer ${tokenString}`; + } + } + const response = await this.request({ + path: `/asset/trash/restore`, + method: 'POST', + headers: headerParameters, + query: queryParameters, + }, initOverrides); + + return new runtime.VoidApiResponse(response); + } + + /** + */ + async restoreTrashOld(initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise { + await this.restoreTrashOldRaw(initOverrides); + } + + /** + */ + async runAssetJobsRaw(requestParameters: RunAssetJobsRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise> { + if (requestParameters.assetJobsDto === null || requestParameters.assetJobsDto === undefined) { + throw new runtime.RequiredError('assetJobsDto','Required parameter requestParameters.assetJobsDto was null or undefined when calling runAssetJobs.'); + } + + const queryParameters: any = {}; + + const headerParameters: runtime.HTTPHeaders = {}; + + headerParameters['Content-Type'] = 'application/json'; + + if (this.configuration && this.configuration.apiKey) { + headerParameters["x-api-key"] = this.configuration.apiKey("x-api-key"); // api_key authentication + } + + if (this.configuration && this.configuration.accessToken) { + const token = this.configuration.accessToken; + const tokenString = await token("bearer", []); + + if (tokenString) { + headerParameters["Authorization"] = `Bearer ${tokenString}`; + } + } + const response = await this.request({ + path: `/asset/jobs`, + method: 'POST', + headers: headerParameters, + query: queryParameters, + body: AssetJobsDtoToJSON(requestParameters.assetJobsDto), + }, initOverrides); + + return new runtime.VoidApiResponse(response); + } + + /** + */ + async runAssetJobs(requestParameters: RunAssetJobsRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise { + await this.runAssetJobsRaw(requestParameters, initOverrides); + } + + /** + */ + async searchAssetsRaw(requestParameters: SearchAssetsRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise>> { + const queryParameters: any = {}; + + if (requestParameters.checksum !== undefined) { + queryParameters['checksum'] = requestParameters.checksum; + } + + if (requestParameters.city !== undefined) { + queryParameters['city'] = requestParameters.city; + } + + if (requestParameters.country !== undefined) { + queryParameters['country'] = requestParameters.country; + } + + if (requestParameters.createdAfter !== undefined) { + queryParameters['createdAfter'] = (requestParameters.createdAfter as any).toISOString(); + } + + if (requestParameters.createdBefore !== undefined) { + queryParameters['createdBefore'] = (requestParameters.createdBefore as any).toISOString(); + } + + if (requestParameters.deviceAssetId !== undefined) { + queryParameters['deviceAssetId'] = requestParameters.deviceAssetId; + } + + if (requestParameters.deviceId !== undefined) { + queryParameters['deviceId'] = requestParameters.deviceId; + } + + if (requestParameters.encodedVideoPath !== undefined) { + queryParameters['encodedVideoPath'] = requestParameters.encodedVideoPath; + } + + if (requestParameters.id !== undefined) { + queryParameters['id'] = requestParameters.id; + } + + if (requestParameters.isArchived !== undefined) { + queryParameters['isArchived'] = requestParameters.isArchived; + } + + if (requestParameters.isEncoded !== undefined) { + queryParameters['isEncoded'] = requestParameters.isEncoded; + } + + if (requestParameters.isExternal !== undefined) { + queryParameters['isExternal'] = requestParameters.isExternal; + } + + if (requestParameters.isFavorite !== undefined) { + queryParameters['isFavorite'] = requestParameters.isFavorite; + } + + if (requestParameters.isMotion !== undefined) { + queryParameters['isMotion'] = requestParameters.isMotion; + } + + if (requestParameters.isOffline !== undefined) { + queryParameters['isOffline'] = requestParameters.isOffline; + } + + if (requestParameters.isReadOnly !== undefined) { + queryParameters['isReadOnly'] = requestParameters.isReadOnly; + } + + if (requestParameters.isVisible !== undefined) { + queryParameters['isVisible'] = requestParameters.isVisible; + } + + if (requestParameters.lensModel !== undefined) { + queryParameters['lensModel'] = requestParameters.lensModel; + } + + if (requestParameters.libraryId !== undefined) { + queryParameters['libraryId'] = requestParameters.libraryId; + } + + if (requestParameters.make !== undefined) { + queryParameters['make'] = requestParameters.make; + } + + if (requestParameters.model !== undefined) { + queryParameters['model'] = requestParameters.model; + } + + if (requestParameters.order !== undefined) { + queryParameters['order'] = requestParameters.order; + } + + if (requestParameters.originalFileName !== undefined) { + queryParameters['originalFileName'] = requestParameters.originalFileName; + } + + if (requestParameters.originalPath !== undefined) { + queryParameters['originalPath'] = requestParameters.originalPath; + } + + if (requestParameters.page !== undefined) { + queryParameters['page'] = requestParameters.page; + } + + if (requestParameters.resizePath !== undefined) { + queryParameters['resizePath'] = requestParameters.resizePath; + } + + if (requestParameters.size !== undefined) { + queryParameters['size'] = requestParameters.size; + } + + if (requestParameters.state !== undefined) { + queryParameters['state'] = requestParameters.state; + } + + if (requestParameters.takenAfter !== undefined) { + queryParameters['takenAfter'] = (requestParameters.takenAfter as any).toISOString(); + } + + if (requestParameters.takenBefore !== undefined) { + queryParameters['takenBefore'] = (requestParameters.takenBefore as any).toISOString(); + } + + if (requestParameters.trashedAfter !== undefined) { + queryParameters['trashedAfter'] = (requestParameters.trashedAfter as any).toISOString(); + } + + if (requestParameters.trashedBefore !== undefined) { + queryParameters['trashedBefore'] = (requestParameters.trashedBefore as any).toISOString(); + } + + if (requestParameters.type !== undefined) { + queryParameters['type'] = requestParameters.type; + } + + if (requestParameters.updatedAfter !== undefined) { + queryParameters['updatedAfter'] = (requestParameters.updatedAfter as any).toISOString(); + } + + if (requestParameters.updatedBefore !== undefined) { + queryParameters['updatedBefore'] = (requestParameters.updatedBefore as any).toISOString(); + } + + if (requestParameters.webpPath !== undefined) { + queryParameters['webpPath'] = requestParameters.webpPath; + } + + if (requestParameters.withDeleted !== undefined) { + queryParameters['withDeleted'] = requestParameters.withDeleted; + } + + if (requestParameters.withExif !== undefined) { + queryParameters['withExif'] = requestParameters.withExif; + } + + if (requestParameters.withPeople !== undefined) { + queryParameters['withPeople'] = requestParameters.withPeople; + } + + if (requestParameters.withStacked !== undefined) { + queryParameters['withStacked'] = requestParameters.withStacked; + } + + const headerParameters: runtime.HTTPHeaders = {}; + + if (this.configuration && this.configuration.apiKey) { + headerParameters["x-api-key"] = this.configuration.apiKey("x-api-key"); // api_key authentication + } + + if (this.configuration && this.configuration.accessToken) { + const token = this.configuration.accessToken; + const tokenString = await token("bearer", []); + + if (tokenString) { + headerParameters["Authorization"] = `Bearer ${tokenString}`; + } + } + const response = await this.request({ + path: `/assets`, + method: 'GET', + headers: headerParameters, + query: queryParameters, + }, initOverrides); + + return new runtime.JSONApiResponse(response, (jsonValue) => jsonValue.map(AssetResponseDtoFromJSON)); + } + + /** + */ + async searchAssets(requestParameters: SearchAssetsRequest = {}, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise> { + const response = await this.searchAssetsRaw(requestParameters, initOverrides); + return await response.value(); + } + + /** + */ + async serveFileRaw(requestParameters: ServeFileRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise> { + if (requestParameters.id === null || requestParameters.id === undefined) { + throw new runtime.RequiredError('id','Required parameter requestParameters.id was null or undefined when calling serveFile.'); + } + + const queryParameters: any = {}; + + if (requestParameters.isThumb !== undefined) { + queryParameters['isThumb'] = requestParameters.isThumb; + } + + if (requestParameters.isWeb !== undefined) { + queryParameters['isWeb'] = requestParameters.isWeb; + } + + if (requestParameters.key !== undefined) { + queryParameters['key'] = requestParameters.key; + } + + const headerParameters: runtime.HTTPHeaders = {}; + + if (this.configuration && this.configuration.apiKey) { + headerParameters["x-api-key"] = this.configuration.apiKey("x-api-key"); // api_key authentication + } + + if (this.configuration && this.configuration.accessToken) { + const token = this.configuration.accessToken; + const tokenString = await token("bearer", []); + + if (tokenString) { + headerParameters["Authorization"] = `Bearer ${tokenString}`; + } + } + const response = await this.request({ + path: `/asset/file/{id}`.replace(`{${"id"}}`, encodeURIComponent(String(requestParameters.id))), + method: 'GET', + headers: headerParameters, + query: queryParameters, + }, initOverrides); + + return new runtime.BlobApiResponse(response); + } + + /** + */ + async serveFile(requestParameters: ServeFileRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise { + const response = await this.serveFileRaw(requestParameters, initOverrides); + return await response.value(); + } + + /** + */ + async updateAssetRaw(requestParameters: UpdateAssetRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise> { + if (requestParameters.id === null || requestParameters.id === undefined) { + throw new runtime.RequiredError('id','Required parameter requestParameters.id was null or undefined when calling updateAsset.'); + } + + if (requestParameters.updateAssetDto === null || requestParameters.updateAssetDto === undefined) { + throw new runtime.RequiredError('updateAssetDto','Required parameter requestParameters.updateAssetDto was null or undefined when calling updateAsset.'); + } + + const queryParameters: any = {}; + + const headerParameters: runtime.HTTPHeaders = {}; + + headerParameters['Content-Type'] = 'application/json'; + + if (this.configuration && this.configuration.apiKey) { + headerParameters["x-api-key"] = this.configuration.apiKey("x-api-key"); // api_key authentication + } + + if (this.configuration && this.configuration.accessToken) { + const token = this.configuration.accessToken; + const tokenString = await token("bearer", []); + + if (tokenString) { + headerParameters["Authorization"] = `Bearer ${tokenString}`; + } + } + const response = await this.request({ + path: `/asset/{id}`.replace(`{${"id"}}`, encodeURIComponent(String(requestParameters.id))), + method: 'PUT', + headers: headerParameters, + query: queryParameters, + body: UpdateAssetDtoToJSON(requestParameters.updateAssetDto), + }, initOverrides); + + return new runtime.JSONApiResponse(response, (jsonValue) => AssetResponseDtoFromJSON(jsonValue)); + } + + /** + */ + async updateAsset(requestParameters: UpdateAssetRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise { + const response = await this.updateAssetRaw(requestParameters, initOverrides); + return await response.value(); + } + + /** + */ + async updateAssetsRaw(requestParameters: UpdateAssetsRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise> { + if (requestParameters.assetBulkUpdateDto === null || requestParameters.assetBulkUpdateDto === undefined) { + throw new runtime.RequiredError('assetBulkUpdateDto','Required parameter requestParameters.assetBulkUpdateDto was null or undefined when calling updateAssets.'); + } + + const queryParameters: any = {}; + + const headerParameters: runtime.HTTPHeaders = {}; + + headerParameters['Content-Type'] = 'application/json'; + + if (this.configuration && this.configuration.apiKey) { + headerParameters["x-api-key"] = this.configuration.apiKey("x-api-key"); // api_key authentication + } + + if (this.configuration && this.configuration.accessToken) { + const token = this.configuration.accessToken; + const tokenString = await token("bearer", []); + + if (tokenString) { + headerParameters["Authorization"] = `Bearer ${tokenString}`; + } + } + const response = await this.request({ + path: `/asset`, + method: 'PUT', + headers: headerParameters, + query: queryParameters, + body: AssetBulkUpdateDtoToJSON(requestParameters.assetBulkUpdateDto), + }, initOverrides); + + return new runtime.VoidApiResponse(response); + } + + /** + */ + async updateAssets(requestParameters: UpdateAssetsRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise { + await this.updateAssetsRaw(requestParameters, initOverrides); + } + + /** + */ + async updateStackParentRaw(requestParameters: UpdateStackParentRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise> { + if (requestParameters.updateStackParentDto === null || requestParameters.updateStackParentDto === undefined) { + throw new runtime.RequiredError('updateStackParentDto','Required parameter requestParameters.updateStackParentDto was null or undefined when calling updateStackParent.'); + } + + const queryParameters: any = {}; + + const headerParameters: runtime.HTTPHeaders = {}; + + headerParameters['Content-Type'] = 'application/json'; + + if (this.configuration && this.configuration.apiKey) { + headerParameters["x-api-key"] = this.configuration.apiKey("x-api-key"); // api_key authentication + } + + if (this.configuration && this.configuration.accessToken) { + const token = this.configuration.accessToken; + const tokenString = await token("bearer", []); + + if (tokenString) { + headerParameters["Authorization"] = `Bearer ${tokenString}`; + } + } + const response = await this.request({ + path: `/asset/stack/parent`, + method: 'PUT', + headers: headerParameters, + query: queryParameters, + body: UpdateStackParentDtoToJSON(requestParameters.updateStackParentDto), + }, initOverrides); + + return new runtime.VoidApiResponse(response); + } + + /** + */ + async updateStackParent(requestParameters: UpdateStackParentRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise { + await this.updateStackParentRaw(requestParameters, initOverrides); + } + + /** + */ + async uploadFileRaw(requestParameters: UploadFileRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise> { + if (requestParameters.assetData === null || requestParameters.assetData === undefined) { + throw new runtime.RequiredError('assetData','Required parameter requestParameters.assetData was null or undefined when calling uploadFile.'); + } + + if (requestParameters.deviceAssetId === null || requestParameters.deviceAssetId === undefined) { + throw new runtime.RequiredError('deviceAssetId','Required parameter requestParameters.deviceAssetId was null or undefined when calling uploadFile.'); + } + + if (requestParameters.deviceId === null || requestParameters.deviceId === undefined) { + throw new runtime.RequiredError('deviceId','Required parameter requestParameters.deviceId was null or undefined when calling uploadFile.'); + } + + if (requestParameters.fileCreatedAt === null || requestParameters.fileCreatedAt === undefined) { + throw new runtime.RequiredError('fileCreatedAt','Required parameter requestParameters.fileCreatedAt was null or undefined when calling uploadFile.'); + } + + if (requestParameters.fileModifiedAt === null || requestParameters.fileModifiedAt === undefined) { + throw new runtime.RequiredError('fileModifiedAt','Required parameter requestParameters.fileModifiedAt was null or undefined when calling uploadFile.'); + } + + const queryParameters: any = {}; + + if (requestParameters.key !== undefined) { + queryParameters['key'] = requestParameters.key; + } + + const headerParameters: runtime.HTTPHeaders = {}; + + if (this.configuration && this.configuration.apiKey) { + headerParameters["x-api-key"] = this.configuration.apiKey("x-api-key"); // api_key authentication + } + + if (this.configuration && this.configuration.accessToken) { + const token = this.configuration.accessToken; + const tokenString = await token("bearer", []); + + if (tokenString) { + headerParameters["Authorization"] = `Bearer ${tokenString}`; + } + } + const consumes: runtime.Consume[] = [ + { contentType: 'multipart/form-data' }, + ]; + // @ts-ignore: canConsumeForm may be unused + const canConsumeForm = runtime.canConsumeForm(consumes); + + let formParams: { append(param: string, value: any): any }; + let useForm = false; + // use FormData to transmit files using content-type "multipart/form-data" + useForm = canConsumeForm; + // use FormData to transmit files using content-type "multipart/form-data" + useForm = canConsumeForm; + // use FormData to transmit files using content-type "multipart/form-data" + useForm = canConsumeForm; + if (useForm) { + formParams = new FormData(); + } else { + formParams = new URLSearchParams(); + } + + if (requestParameters.assetData !== undefined) { + formParams.append('assetData', requestParameters.assetData as any); + } + + if (requestParameters.deviceAssetId !== undefined) { + formParams.append('deviceAssetId', requestParameters.deviceAssetId as any); + } + + if (requestParameters.deviceId !== undefined) { + formParams.append('deviceId', requestParameters.deviceId as any); + } + + if (requestParameters.duration !== undefined) { + formParams.append('duration', requestParameters.duration as any); + } + + if (requestParameters.fileCreatedAt !== undefined) { + formParams.append('fileCreatedAt', requestParameters.fileCreatedAt as any); + } + + if (requestParameters.fileModifiedAt !== undefined) { + formParams.append('fileModifiedAt', requestParameters.fileModifiedAt as any); + } + + if (requestParameters.isArchived !== undefined) { + formParams.append('isArchived', requestParameters.isArchived as any); + } + + if (requestParameters.isExternal !== undefined) { + formParams.append('isExternal', requestParameters.isExternal as any); + } + + if (requestParameters.isFavorite !== undefined) { + formParams.append('isFavorite', requestParameters.isFavorite as any); + } + + if (requestParameters.isOffline !== undefined) { + formParams.append('isOffline', requestParameters.isOffline as any); + } + + if (requestParameters.isReadOnly !== undefined) { + formParams.append('isReadOnly', requestParameters.isReadOnly as any); + } + + if (requestParameters.isVisible !== undefined) { + formParams.append('isVisible', requestParameters.isVisible as any); + } + + if (requestParameters.libraryId !== undefined) { + formParams.append('libraryId', requestParameters.libraryId as any); + } + + if (requestParameters.livePhotoData !== undefined) { + formParams.append('livePhotoData', requestParameters.livePhotoData as any); + } + + if (requestParameters.sidecarData !== undefined) { + formParams.append('sidecarData', requestParameters.sidecarData as any); + } + + const response = await this.request({ + path: `/asset/upload`, + method: 'POST', + headers: headerParameters, + query: queryParameters, + body: formParams, + }, initOverrides); + + return new runtime.JSONApiResponse(response, (jsonValue) => AssetFileUploadResponseDtoFromJSON(jsonValue)); + } + + /** + */ + async uploadFile(requestParameters: UploadFileRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise { + const response = await this.uploadFileRaw(requestParameters, initOverrides); + return await response.value(); + } + +} diff --git a/open-api/typescript-sdk/fetch-client/apis/AuditApi.ts b/open-api/typescript-sdk/fetch-client/apis/AuditApi.ts new file mode 100644 index 0000000000..5c8fd0f4a3 --- /dev/null +++ b/open-api/typescript-sdk/fetch-client/apis/AuditApi.ts @@ -0,0 +1,236 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * Immich + * Immich API + * + * The version of the OpenAPI document: 1.94.1 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + + +import * as runtime from '../runtime'; +import type { + AuditDeletesResponseDto, + EntityType, + FileChecksumDto, + FileChecksumResponseDto, + FileReportDto, + FileReportFixDto, +} from '../models/index'; +import { + AuditDeletesResponseDtoFromJSON, + AuditDeletesResponseDtoToJSON, + EntityTypeFromJSON, + EntityTypeToJSON, + FileChecksumDtoFromJSON, + FileChecksumDtoToJSON, + FileChecksumResponseDtoFromJSON, + FileChecksumResponseDtoToJSON, + FileReportDtoFromJSON, + FileReportDtoToJSON, + FileReportFixDtoFromJSON, + FileReportFixDtoToJSON, +} from '../models/index'; + +export interface FixAuditFilesRequest { + fileReportFixDto: FileReportFixDto; +} + +export interface GetAuditDeletesRequest { + after: Date; + entityType: EntityType; + userId?: string; +} + +export interface GetFileChecksumsRequest { + fileChecksumDto: FileChecksumDto; +} + +/** + * + */ +export class AuditApi extends runtime.BaseAPI { + + /** + */ + async fixAuditFilesRaw(requestParameters: FixAuditFilesRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise> { + if (requestParameters.fileReportFixDto === null || requestParameters.fileReportFixDto === undefined) { + throw new runtime.RequiredError('fileReportFixDto','Required parameter requestParameters.fileReportFixDto was null or undefined when calling fixAuditFiles.'); + } + + const queryParameters: any = {}; + + const headerParameters: runtime.HTTPHeaders = {}; + + headerParameters['Content-Type'] = 'application/json'; + + if (this.configuration && this.configuration.apiKey) { + headerParameters["x-api-key"] = this.configuration.apiKey("x-api-key"); // api_key authentication + } + + if (this.configuration && this.configuration.accessToken) { + const token = this.configuration.accessToken; + const tokenString = await token("bearer", []); + + if (tokenString) { + headerParameters["Authorization"] = `Bearer ${tokenString}`; + } + } + const response = await this.request({ + path: `/audit/file-report/fix`, + method: 'POST', + headers: headerParameters, + query: queryParameters, + body: FileReportFixDtoToJSON(requestParameters.fileReportFixDto), + }, initOverrides); + + return new runtime.VoidApiResponse(response); + } + + /** + */ + async fixAuditFiles(requestParameters: FixAuditFilesRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise { + await this.fixAuditFilesRaw(requestParameters, initOverrides); + } + + /** + */ + async getAuditDeletesRaw(requestParameters: GetAuditDeletesRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise> { + if (requestParameters.after === null || requestParameters.after === undefined) { + throw new runtime.RequiredError('after','Required parameter requestParameters.after was null or undefined when calling getAuditDeletes.'); + } + + if (requestParameters.entityType === null || requestParameters.entityType === undefined) { + throw new runtime.RequiredError('entityType','Required parameter requestParameters.entityType was null or undefined when calling getAuditDeletes.'); + } + + const queryParameters: any = {}; + + if (requestParameters.after !== undefined) { + queryParameters['after'] = (requestParameters.after as any).toISOString(); + } + + if (requestParameters.entityType !== undefined) { + queryParameters['entityType'] = requestParameters.entityType; + } + + if (requestParameters.userId !== undefined) { + queryParameters['userId'] = requestParameters.userId; + } + + const headerParameters: runtime.HTTPHeaders = {}; + + if (this.configuration && this.configuration.apiKey) { + headerParameters["x-api-key"] = this.configuration.apiKey("x-api-key"); // api_key authentication + } + + if (this.configuration && this.configuration.accessToken) { + const token = this.configuration.accessToken; + const tokenString = await token("bearer", []); + + if (tokenString) { + headerParameters["Authorization"] = `Bearer ${tokenString}`; + } + } + const response = await this.request({ + path: `/audit/deletes`, + method: 'GET', + headers: headerParameters, + query: queryParameters, + }, initOverrides); + + return new runtime.JSONApiResponse(response, (jsonValue) => AuditDeletesResponseDtoFromJSON(jsonValue)); + } + + /** + */ + async getAuditDeletes(requestParameters: GetAuditDeletesRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise { + const response = await this.getAuditDeletesRaw(requestParameters, initOverrides); + return await response.value(); + } + + /** + */ + async getAuditFilesRaw(initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise> { + const queryParameters: any = {}; + + const headerParameters: runtime.HTTPHeaders = {}; + + if (this.configuration && this.configuration.apiKey) { + headerParameters["x-api-key"] = this.configuration.apiKey("x-api-key"); // api_key authentication + } + + if (this.configuration && this.configuration.accessToken) { + const token = this.configuration.accessToken; + const tokenString = await token("bearer", []); + + if (tokenString) { + headerParameters["Authorization"] = `Bearer ${tokenString}`; + } + } + const response = await this.request({ + path: `/audit/file-report`, + method: 'GET', + headers: headerParameters, + query: queryParameters, + }, initOverrides); + + return new runtime.JSONApiResponse(response, (jsonValue) => FileReportDtoFromJSON(jsonValue)); + } + + /** + */ + async getAuditFiles(initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise { + const response = await this.getAuditFilesRaw(initOverrides); + return await response.value(); + } + + /** + */ + async getFileChecksumsRaw(requestParameters: GetFileChecksumsRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise>> { + if (requestParameters.fileChecksumDto === null || requestParameters.fileChecksumDto === undefined) { + throw new runtime.RequiredError('fileChecksumDto','Required parameter requestParameters.fileChecksumDto was null or undefined when calling getFileChecksums.'); + } + + const queryParameters: any = {}; + + const headerParameters: runtime.HTTPHeaders = {}; + + headerParameters['Content-Type'] = 'application/json'; + + if (this.configuration && this.configuration.apiKey) { + headerParameters["x-api-key"] = this.configuration.apiKey("x-api-key"); // api_key authentication + } + + if (this.configuration && this.configuration.accessToken) { + const token = this.configuration.accessToken; + const tokenString = await token("bearer", []); + + if (tokenString) { + headerParameters["Authorization"] = `Bearer ${tokenString}`; + } + } + const response = await this.request({ + path: `/audit/file-report/checksum`, + method: 'POST', + headers: headerParameters, + query: queryParameters, + body: FileChecksumDtoToJSON(requestParameters.fileChecksumDto), + }, initOverrides); + + return new runtime.JSONApiResponse(response, (jsonValue) => jsonValue.map(FileChecksumResponseDtoFromJSON)); + } + + /** + */ + async getFileChecksums(requestParameters: GetFileChecksumsRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise> { + const response = await this.getFileChecksumsRaw(requestParameters, initOverrides); + return await response.value(); + } + +} diff --git a/open-api/typescript-sdk/fetch-client/apis/AuthenticationApi.ts b/open-api/typescript-sdk/fetch-client/apis/AuthenticationApi.ts new file mode 100644 index 0000000000..3580a35a59 --- /dev/null +++ b/open-api/typescript-sdk/fetch-client/apis/AuthenticationApi.ts @@ -0,0 +1,354 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * Immich + * Immich API + * + * The version of the OpenAPI document: 1.94.1 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + + +import * as runtime from '../runtime'; +import type { + AuthDeviceResponseDto, + ChangePasswordDto, + LoginCredentialDto, + LoginResponseDto, + LogoutResponseDto, + SignUpDto, + UserResponseDto, + ValidateAccessTokenResponseDto, +} from '../models/index'; +import { + AuthDeviceResponseDtoFromJSON, + AuthDeviceResponseDtoToJSON, + ChangePasswordDtoFromJSON, + ChangePasswordDtoToJSON, + LoginCredentialDtoFromJSON, + LoginCredentialDtoToJSON, + LoginResponseDtoFromJSON, + LoginResponseDtoToJSON, + LogoutResponseDtoFromJSON, + LogoutResponseDtoToJSON, + SignUpDtoFromJSON, + SignUpDtoToJSON, + UserResponseDtoFromJSON, + UserResponseDtoToJSON, + ValidateAccessTokenResponseDtoFromJSON, + ValidateAccessTokenResponseDtoToJSON, +} from '../models/index'; + +export interface ChangePasswordRequest { + changePasswordDto: ChangePasswordDto; +} + +export interface LoginRequest { + loginCredentialDto: LoginCredentialDto; +} + +export interface LogoutAuthDeviceRequest { + id: string; +} + +export interface SignUpAdminRequest { + signUpDto: SignUpDto; +} + +/** + * + */ +export class AuthenticationApi extends runtime.BaseAPI { + + /** + */ + async changePasswordRaw(requestParameters: ChangePasswordRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise> { + if (requestParameters.changePasswordDto === null || requestParameters.changePasswordDto === undefined) { + throw new runtime.RequiredError('changePasswordDto','Required parameter requestParameters.changePasswordDto was null or undefined when calling changePassword.'); + } + + const queryParameters: any = {}; + + const headerParameters: runtime.HTTPHeaders = {}; + + headerParameters['Content-Type'] = 'application/json'; + + if (this.configuration && this.configuration.apiKey) { + headerParameters["x-api-key"] = this.configuration.apiKey("x-api-key"); // api_key authentication + } + + if (this.configuration && this.configuration.accessToken) { + const token = this.configuration.accessToken; + const tokenString = await token("bearer", []); + + if (tokenString) { + headerParameters["Authorization"] = `Bearer ${tokenString}`; + } + } + const response = await this.request({ + path: `/auth/change-password`, + method: 'POST', + headers: headerParameters, + query: queryParameters, + body: ChangePasswordDtoToJSON(requestParameters.changePasswordDto), + }, initOverrides); + + return new runtime.JSONApiResponse(response, (jsonValue) => UserResponseDtoFromJSON(jsonValue)); + } + + /** + */ + async changePassword(requestParameters: ChangePasswordRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise { + const response = await this.changePasswordRaw(requestParameters, initOverrides); + return await response.value(); + } + + /** + */ + async getAuthDevicesRaw(initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise>> { + const queryParameters: any = {}; + + const headerParameters: runtime.HTTPHeaders = {}; + + if (this.configuration && this.configuration.apiKey) { + headerParameters["x-api-key"] = this.configuration.apiKey("x-api-key"); // api_key authentication + } + + if (this.configuration && this.configuration.accessToken) { + const token = this.configuration.accessToken; + const tokenString = await token("bearer", []); + + if (tokenString) { + headerParameters["Authorization"] = `Bearer ${tokenString}`; + } + } + const response = await this.request({ + path: `/auth/devices`, + method: 'GET', + headers: headerParameters, + query: queryParameters, + }, initOverrides); + + return new runtime.JSONApiResponse(response, (jsonValue) => jsonValue.map(AuthDeviceResponseDtoFromJSON)); + } + + /** + */ + async getAuthDevices(initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise> { + const response = await this.getAuthDevicesRaw(initOverrides); + return await response.value(); + } + + /** + */ + async loginRaw(requestParameters: LoginRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise> { + if (requestParameters.loginCredentialDto === null || requestParameters.loginCredentialDto === undefined) { + throw new runtime.RequiredError('loginCredentialDto','Required parameter requestParameters.loginCredentialDto was null or undefined when calling login.'); + } + + const queryParameters: any = {}; + + const headerParameters: runtime.HTTPHeaders = {}; + + headerParameters['Content-Type'] = 'application/json'; + + const response = await this.request({ + path: `/auth/login`, + method: 'POST', + headers: headerParameters, + query: queryParameters, + body: LoginCredentialDtoToJSON(requestParameters.loginCredentialDto), + }, initOverrides); + + return new runtime.JSONApiResponse(response, (jsonValue) => LoginResponseDtoFromJSON(jsonValue)); + } + + /** + */ + async login(requestParameters: LoginRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise { + const response = await this.loginRaw(requestParameters, initOverrides); + return await response.value(); + } + + /** + */ + async logoutRaw(initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise> { + const queryParameters: any = {}; + + const headerParameters: runtime.HTTPHeaders = {}; + + if (this.configuration && this.configuration.apiKey) { + headerParameters["x-api-key"] = this.configuration.apiKey("x-api-key"); // api_key authentication + } + + if (this.configuration && this.configuration.accessToken) { + const token = this.configuration.accessToken; + const tokenString = await token("bearer", []); + + if (tokenString) { + headerParameters["Authorization"] = `Bearer ${tokenString}`; + } + } + const response = await this.request({ + path: `/auth/logout`, + method: 'POST', + headers: headerParameters, + query: queryParameters, + }, initOverrides); + + return new runtime.JSONApiResponse(response, (jsonValue) => LogoutResponseDtoFromJSON(jsonValue)); + } + + /** + */ + async logout(initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise { + const response = await this.logoutRaw(initOverrides); + return await response.value(); + } + + /** + */ + async logoutAuthDeviceRaw(requestParameters: LogoutAuthDeviceRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise> { + if (requestParameters.id === null || requestParameters.id === undefined) { + throw new runtime.RequiredError('id','Required parameter requestParameters.id was null or undefined when calling logoutAuthDevice.'); + } + + const queryParameters: any = {}; + + const headerParameters: runtime.HTTPHeaders = {}; + + if (this.configuration && this.configuration.apiKey) { + headerParameters["x-api-key"] = this.configuration.apiKey("x-api-key"); // api_key authentication + } + + if (this.configuration && this.configuration.accessToken) { + const token = this.configuration.accessToken; + const tokenString = await token("bearer", []); + + if (tokenString) { + headerParameters["Authorization"] = `Bearer ${tokenString}`; + } + } + const response = await this.request({ + path: `/auth/devices/{id}`.replace(`{${"id"}}`, encodeURIComponent(String(requestParameters.id))), + method: 'DELETE', + headers: headerParameters, + query: queryParameters, + }, initOverrides); + + return new runtime.VoidApiResponse(response); + } + + /** + */ + async logoutAuthDevice(requestParameters: LogoutAuthDeviceRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise { + await this.logoutAuthDeviceRaw(requestParameters, initOverrides); + } + + /** + */ + async logoutAuthDevicesRaw(initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise> { + const queryParameters: any = {}; + + const headerParameters: runtime.HTTPHeaders = {}; + + if (this.configuration && this.configuration.apiKey) { + headerParameters["x-api-key"] = this.configuration.apiKey("x-api-key"); // api_key authentication + } + + if (this.configuration && this.configuration.accessToken) { + const token = this.configuration.accessToken; + const tokenString = await token("bearer", []); + + if (tokenString) { + headerParameters["Authorization"] = `Bearer ${tokenString}`; + } + } + const response = await this.request({ + path: `/auth/devices`, + method: 'DELETE', + headers: headerParameters, + query: queryParameters, + }, initOverrides); + + return new runtime.VoidApiResponse(response); + } + + /** + */ + async logoutAuthDevices(initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise { + await this.logoutAuthDevicesRaw(initOverrides); + } + + /** + */ + async signUpAdminRaw(requestParameters: SignUpAdminRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise> { + if (requestParameters.signUpDto === null || requestParameters.signUpDto === undefined) { + throw new runtime.RequiredError('signUpDto','Required parameter requestParameters.signUpDto was null or undefined when calling signUpAdmin.'); + } + + const queryParameters: any = {}; + + const headerParameters: runtime.HTTPHeaders = {}; + + headerParameters['Content-Type'] = 'application/json'; + + const response = await this.request({ + path: `/auth/admin-sign-up`, + method: 'POST', + headers: headerParameters, + query: queryParameters, + body: SignUpDtoToJSON(requestParameters.signUpDto), + }, initOverrides); + + return new runtime.JSONApiResponse(response, (jsonValue) => UserResponseDtoFromJSON(jsonValue)); + } + + /** + */ + async signUpAdmin(requestParameters: SignUpAdminRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise { + const response = await this.signUpAdminRaw(requestParameters, initOverrides); + return await response.value(); + } + + /** + */ + async validateAccessTokenRaw(initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise> { + const queryParameters: any = {}; + + const headerParameters: runtime.HTTPHeaders = {}; + + if (this.configuration && this.configuration.apiKey) { + headerParameters["x-api-key"] = this.configuration.apiKey("x-api-key"); // api_key authentication + } + + if (this.configuration && this.configuration.accessToken) { + const token = this.configuration.accessToken; + const tokenString = await token("bearer", []); + + if (tokenString) { + headerParameters["Authorization"] = `Bearer ${tokenString}`; + } + } + const response = await this.request({ + path: `/auth/validateToken`, + method: 'POST', + headers: headerParameters, + query: queryParameters, + }, initOverrides); + + return new runtime.JSONApiResponse(response, (jsonValue) => ValidateAccessTokenResponseDtoFromJSON(jsonValue)); + } + + /** + */ + async validateAccessToken(initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise { + const response = await this.validateAccessTokenRaw(initOverrides); + return await response.value(); + } + +} diff --git a/open-api/typescript-sdk/fetch-client/apis/DownloadApi.ts b/open-api/typescript-sdk/fetch-client/apis/DownloadApi.ts new file mode 100644 index 0000000000..7884b9848f --- /dev/null +++ b/open-api/typescript-sdk/fetch-client/apis/DownloadApi.ts @@ -0,0 +1,189 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * Immich + * Immich API + * + * The version of the OpenAPI document: 1.94.1 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + + +import * as runtime from '../runtime'; +import type { + AssetIdsDto, + DownloadInfoDto, + DownloadResponseDto, +} from '../models/index'; +import { + AssetIdsDtoFromJSON, + AssetIdsDtoToJSON, + DownloadInfoDtoFromJSON, + DownloadInfoDtoToJSON, + DownloadResponseDtoFromJSON, + DownloadResponseDtoToJSON, +} from '../models/index'; + +export interface DownloadArchiveRequest { + assetIdsDto: AssetIdsDto; + key?: string; +} + +export interface DownloadFileRequest { + id: string; + key?: string; +} + +export interface GetDownloadInfoRequest { + downloadInfoDto: DownloadInfoDto; + key?: string; +} + +/** + * + */ +export class DownloadApi extends runtime.BaseAPI { + + /** + */ + async downloadArchiveRaw(requestParameters: DownloadArchiveRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise> { + if (requestParameters.assetIdsDto === null || requestParameters.assetIdsDto === undefined) { + throw new runtime.RequiredError('assetIdsDto','Required parameter requestParameters.assetIdsDto was null or undefined when calling downloadArchive.'); + } + + const queryParameters: any = {}; + + if (requestParameters.key !== undefined) { + queryParameters['key'] = requestParameters.key; + } + + const headerParameters: runtime.HTTPHeaders = {}; + + headerParameters['Content-Type'] = 'application/json'; + + if (this.configuration && this.configuration.apiKey) { + headerParameters["x-api-key"] = this.configuration.apiKey("x-api-key"); // api_key authentication + } + + if (this.configuration && this.configuration.accessToken) { + const token = this.configuration.accessToken; + const tokenString = await token("bearer", []); + + if (tokenString) { + headerParameters["Authorization"] = `Bearer ${tokenString}`; + } + } + const response = await this.request({ + path: `/download/archive`, + method: 'POST', + headers: headerParameters, + query: queryParameters, + body: AssetIdsDtoToJSON(requestParameters.assetIdsDto), + }, initOverrides); + + return new runtime.BlobApiResponse(response); + } + + /** + */ + async downloadArchive(requestParameters: DownloadArchiveRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise { + const response = await this.downloadArchiveRaw(requestParameters, initOverrides); + return await response.value(); + } + + /** + */ + async downloadFileRaw(requestParameters: DownloadFileRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise> { + if (requestParameters.id === null || requestParameters.id === undefined) { + throw new runtime.RequiredError('id','Required parameter requestParameters.id was null or undefined when calling downloadFile.'); + } + + const queryParameters: any = {}; + + if (requestParameters.key !== undefined) { + queryParameters['key'] = requestParameters.key; + } + + const headerParameters: runtime.HTTPHeaders = {}; + + if (this.configuration && this.configuration.apiKey) { + headerParameters["x-api-key"] = this.configuration.apiKey("x-api-key"); // api_key authentication + } + + if (this.configuration && this.configuration.accessToken) { + const token = this.configuration.accessToken; + const tokenString = await token("bearer", []); + + if (tokenString) { + headerParameters["Authorization"] = `Bearer ${tokenString}`; + } + } + const response = await this.request({ + path: `/download/asset/{id}`.replace(`{${"id"}}`, encodeURIComponent(String(requestParameters.id))), + method: 'POST', + headers: headerParameters, + query: queryParameters, + }, initOverrides); + + return new runtime.BlobApiResponse(response); + } + + /** + */ + async downloadFile(requestParameters: DownloadFileRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise { + const response = await this.downloadFileRaw(requestParameters, initOverrides); + return await response.value(); + } + + /** + */ + async getDownloadInfoRaw(requestParameters: GetDownloadInfoRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise> { + if (requestParameters.downloadInfoDto === null || requestParameters.downloadInfoDto === undefined) { + throw new runtime.RequiredError('downloadInfoDto','Required parameter requestParameters.downloadInfoDto was null or undefined when calling getDownloadInfo.'); + } + + const queryParameters: any = {}; + + if (requestParameters.key !== undefined) { + queryParameters['key'] = requestParameters.key; + } + + const headerParameters: runtime.HTTPHeaders = {}; + + headerParameters['Content-Type'] = 'application/json'; + + if (this.configuration && this.configuration.apiKey) { + headerParameters["x-api-key"] = this.configuration.apiKey("x-api-key"); // api_key authentication + } + + if (this.configuration && this.configuration.accessToken) { + const token = this.configuration.accessToken; + const tokenString = await token("bearer", []); + + if (tokenString) { + headerParameters["Authorization"] = `Bearer ${tokenString}`; + } + } + const response = await this.request({ + path: `/download/info`, + method: 'POST', + headers: headerParameters, + query: queryParameters, + body: DownloadInfoDtoToJSON(requestParameters.downloadInfoDto), + }, initOverrides); + + return new runtime.JSONApiResponse(response, (jsonValue) => DownloadResponseDtoFromJSON(jsonValue)); + } + + /** + */ + async getDownloadInfo(requestParameters: GetDownloadInfoRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise { + const response = await this.getDownloadInfoRaw(requestParameters, initOverrides); + return await response.value(); + } + +} diff --git a/open-api/typescript-sdk/fetch-client/apis/FaceApi.ts b/open-api/typescript-sdk/fetch-client/apis/FaceApi.ts new file mode 100644 index 0000000000..2f86896b66 --- /dev/null +++ b/open-api/typescript-sdk/fetch-client/apis/FaceApi.ts @@ -0,0 +1,136 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * Immich + * Immich API + * + * The version of the OpenAPI document: 1.94.1 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + + +import * as runtime from '../runtime'; +import type { + AssetFaceResponseDto, + FaceDto, + PersonResponseDto, +} from '../models/index'; +import { + AssetFaceResponseDtoFromJSON, + AssetFaceResponseDtoToJSON, + FaceDtoFromJSON, + FaceDtoToJSON, + PersonResponseDtoFromJSON, + PersonResponseDtoToJSON, +} from '../models/index'; + +export interface GetFacesRequest { + id: string; +} + +export interface ReassignFacesByIdRequest { + id: string; + faceDto: FaceDto; +} + +/** + * + */ +export class FaceApi extends runtime.BaseAPI { + + /** + */ + async getFacesRaw(requestParameters: GetFacesRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise>> { + if (requestParameters.id === null || requestParameters.id === undefined) { + throw new runtime.RequiredError('id','Required parameter requestParameters.id was null or undefined when calling getFaces.'); + } + + const queryParameters: any = {}; + + if (requestParameters.id !== undefined) { + queryParameters['id'] = requestParameters.id; + } + + const headerParameters: runtime.HTTPHeaders = {}; + + if (this.configuration && this.configuration.apiKey) { + headerParameters["x-api-key"] = this.configuration.apiKey("x-api-key"); // api_key authentication + } + + if (this.configuration && this.configuration.accessToken) { + const token = this.configuration.accessToken; + const tokenString = await token("bearer", []); + + if (tokenString) { + headerParameters["Authorization"] = `Bearer ${tokenString}`; + } + } + const response = await this.request({ + path: `/face`, + method: 'GET', + headers: headerParameters, + query: queryParameters, + }, initOverrides); + + return new runtime.JSONApiResponse(response, (jsonValue) => jsonValue.map(AssetFaceResponseDtoFromJSON)); + } + + /** + */ + async getFaces(requestParameters: GetFacesRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise> { + const response = await this.getFacesRaw(requestParameters, initOverrides); + return await response.value(); + } + + /** + */ + async reassignFacesByIdRaw(requestParameters: ReassignFacesByIdRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise> { + if (requestParameters.id === null || requestParameters.id === undefined) { + throw new runtime.RequiredError('id','Required parameter requestParameters.id was null or undefined when calling reassignFacesById.'); + } + + if (requestParameters.faceDto === null || requestParameters.faceDto === undefined) { + throw new runtime.RequiredError('faceDto','Required parameter requestParameters.faceDto was null or undefined when calling reassignFacesById.'); + } + + const queryParameters: any = {}; + + const headerParameters: runtime.HTTPHeaders = {}; + + headerParameters['Content-Type'] = 'application/json'; + + if (this.configuration && this.configuration.apiKey) { + headerParameters["x-api-key"] = this.configuration.apiKey("x-api-key"); // api_key authentication + } + + if (this.configuration && this.configuration.accessToken) { + const token = this.configuration.accessToken; + const tokenString = await token("bearer", []); + + if (tokenString) { + headerParameters["Authorization"] = `Bearer ${tokenString}`; + } + } + const response = await this.request({ + path: `/face/{id}`.replace(`{${"id"}}`, encodeURIComponent(String(requestParameters.id))), + method: 'PUT', + headers: headerParameters, + query: queryParameters, + body: FaceDtoToJSON(requestParameters.faceDto), + }, initOverrides); + + return new runtime.JSONApiResponse(response, (jsonValue) => PersonResponseDtoFromJSON(jsonValue)); + } + + /** + */ + async reassignFacesById(requestParameters: ReassignFacesByIdRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise { + const response = await this.reassignFacesByIdRaw(requestParameters, initOverrides); + return await response.value(); + } + +} diff --git a/open-api/typescript-sdk/fetch-client/apis/JobApi.ts b/open-api/typescript-sdk/fetch-client/apis/JobApi.ts new file mode 100644 index 0000000000..3ec0b2f4e6 --- /dev/null +++ b/open-api/typescript-sdk/fetch-client/apis/JobApi.ts @@ -0,0 +1,127 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * Immich + * Immich API + * + * The version of the OpenAPI document: 1.94.1 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + + +import * as runtime from '../runtime'; +import type { + AllJobStatusResponseDto, + JobCommandDto, + JobName, + JobStatusDto, +} from '../models/index'; +import { + AllJobStatusResponseDtoFromJSON, + AllJobStatusResponseDtoToJSON, + JobCommandDtoFromJSON, + JobCommandDtoToJSON, + JobNameFromJSON, + JobNameToJSON, + JobStatusDtoFromJSON, + JobStatusDtoToJSON, +} from '../models/index'; + +export interface SendJobCommandRequest { + id: JobName; + jobCommandDto: JobCommandDto; +} + +/** + * + */ +export class JobApi extends runtime.BaseAPI { + + /** + */ + async getAllJobsStatusRaw(initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise> { + const queryParameters: any = {}; + + const headerParameters: runtime.HTTPHeaders = {}; + + if (this.configuration && this.configuration.apiKey) { + headerParameters["x-api-key"] = this.configuration.apiKey("x-api-key"); // api_key authentication + } + + if (this.configuration && this.configuration.accessToken) { + const token = this.configuration.accessToken; + const tokenString = await token("bearer", []); + + if (tokenString) { + headerParameters["Authorization"] = `Bearer ${tokenString}`; + } + } + const response = await this.request({ + path: `/jobs`, + method: 'GET', + headers: headerParameters, + query: queryParameters, + }, initOverrides); + + return new runtime.JSONApiResponse(response, (jsonValue) => AllJobStatusResponseDtoFromJSON(jsonValue)); + } + + /** + */ + async getAllJobsStatus(initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise { + const response = await this.getAllJobsStatusRaw(initOverrides); + return await response.value(); + } + + /** + */ + async sendJobCommandRaw(requestParameters: SendJobCommandRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise> { + if (requestParameters.id === null || requestParameters.id === undefined) { + throw new runtime.RequiredError('id','Required parameter requestParameters.id was null or undefined when calling sendJobCommand.'); + } + + if (requestParameters.jobCommandDto === null || requestParameters.jobCommandDto === undefined) { + throw new runtime.RequiredError('jobCommandDto','Required parameter requestParameters.jobCommandDto was null or undefined when calling sendJobCommand.'); + } + + const queryParameters: any = {}; + + const headerParameters: runtime.HTTPHeaders = {}; + + headerParameters['Content-Type'] = 'application/json'; + + if (this.configuration && this.configuration.apiKey) { + headerParameters["x-api-key"] = this.configuration.apiKey("x-api-key"); // api_key authentication + } + + if (this.configuration && this.configuration.accessToken) { + const token = this.configuration.accessToken; + const tokenString = await token("bearer", []); + + if (tokenString) { + headerParameters["Authorization"] = `Bearer ${tokenString}`; + } + } + const response = await this.request({ + path: `/jobs/{id}`.replace(`{${"id"}}`, encodeURIComponent(String(requestParameters.id))), + method: 'PUT', + headers: headerParameters, + query: queryParameters, + body: JobCommandDtoToJSON(requestParameters.jobCommandDto), + }, initOverrides); + + return new runtime.JSONApiResponse(response, (jsonValue) => JobStatusDtoFromJSON(jsonValue)); + } + + /** + */ + async sendJobCommand(requestParameters: SendJobCommandRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise { + const response = await this.sendJobCommandRaw(requestParameters, initOverrides); + return await response.value(); + } + +} diff --git a/open-api/typescript-sdk/fetch-client/apis/LibraryApi.ts b/open-api/typescript-sdk/fetch-client/apis/LibraryApi.ts new file mode 100644 index 0000000000..7a3f06b680 --- /dev/null +++ b/open-api/typescript-sdk/fetch-client/apis/LibraryApi.ts @@ -0,0 +1,402 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * Immich + * Immich API + * + * The version of the OpenAPI document: 1.94.1 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + + +import * as runtime from '../runtime'; +import type { + CreateLibraryDto, + LibraryResponseDto, + LibraryStatsResponseDto, + ScanLibraryDto, + UpdateLibraryDto, +} from '../models/index'; +import { + CreateLibraryDtoFromJSON, + CreateLibraryDtoToJSON, + LibraryResponseDtoFromJSON, + LibraryResponseDtoToJSON, + LibraryStatsResponseDtoFromJSON, + LibraryStatsResponseDtoToJSON, + ScanLibraryDtoFromJSON, + ScanLibraryDtoToJSON, + UpdateLibraryDtoFromJSON, + UpdateLibraryDtoToJSON, +} from '../models/index'; + +export interface CreateLibraryRequest { + createLibraryDto: CreateLibraryDto; +} + +export interface DeleteLibraryRequest { + id: string; +} + +export interface GetLibraryInfoRequest { + id: string; +} + +export interface GetLibraryStatisticsRequest { + id: string; +} + +export interface RemoveOfflineFilesRequest { + id: string; +} + +export interface ScanLibraryRequest { + id: string; + scanLibraryDto: ScanLibraryDto; +} + +export interface UpdateLibraryRequest { + id: string; + updateLibraryDto: UpdateLibraryDto; +} + +/** + * + */ +export class LibraryApi extends runtime.BaseAPI { + + /** + */ + async createLibraryRaw(requestParameters: CreateLibraryRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise> { + if (requestParameters.createLibraryDto === null || requestParameters.createLibraryDto === undefined) { + throw new runtime.RequiredError('createLibraryDto','Required parameter requestParameters.createLibraryDto was null or undefined when calling createLibrary.'); + } + + const queryParameters: any = {}; + + const headerParameters: runtime.HTTPHeaders = {}; + + headerParameters['Content-Type'] = 'application/json'; + + if (this.configuration && this.configuration.apiKey) { + headerParameters["x-api-key"] = this.configuration.apiKey("x-api-key"); // api_key authentication + } + + if (this.configuration && this.configuration.accessToken) { + const token = this.configuration.accessToken; + const tokenString = await token("bearer", []); + + if (tokenString) { + headerParameters["Authorization"] = `Bearer ${tokenString}`; + } + } + const response = await this.request({ + path: `/library`, + method: 'POST', + headers: headerParameters, + query: queryParameters, + body: CreateLibraryDtoToJSON(requestParameters.createLibraryDto), + }, initOverrides); + + return new runtime.JSONApiResponse(response, (jsonValue) => LibraryResponseDtoFromJSON(jsonValue)); + } + + /** + */ + async createLibrary(requestParameters: CreateLibraryRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise { + const response = await this.createLibraryRaw(requestParameters, initOverrides); + return await response.value(); + } + + /** + */ + async deleteLibraryRaw(requestParameters: DeleteLibraryRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise> { + if (requestParameters.id === null || requestParameters.id === undefined) { + throw new runtime.RequiredError('id','Required parameter requestParameters.id was null or undefined when calling deleteLibrary.'); + } + + const queryParameters: any = {}; + + const headerParameters: runtime.HTTPHeaders = {}; + + if (this.configuration && this.configuration.apiKey) { + headerParameters["x-api-key"] = this.configuration.apiKey("x-api-key"); // api_key authentication + } + + if (this.configuration && this.configuration.accessToken) { + const token = this.configuration.accessToken; + const tokenString = await token("bearer", []); + + if (tokenString) { + headerParameters["Authorization"] = `Bearer ${tokenString}`; + } + } + const response = await this.request({ + path: `/library/{id}`.replace(`{${"id"}}`, encodeURIComponent(String(requestParameters.id))), + method: 'DELETE', + headers: headerParameters, + query: queryParameters, + }, initOverrides); + + return new runtime.VoidApiResponse(response); + } + + /** + */ + async deleteLibrary(requestParameters: DeleteLibraryRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise { + await this.deleteLibraryRaw(requestParameters, initOverrides); + } + + /** + */ + async getLibrariesRaw(initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise>> { + const queryParameters: any = {}; + + const headerParameters: runtime.HTTPHeaders = {}; + + if (this.configuration && this.configuration.apiKey) { + headerParameters["x-api-key"] = this.configuration.apiKey("x-api-key"); // api_key authentication + } + + if (this.configuration && this.configuration.accessToken) { + const token = this.configuration.accessToken; + const tokenString = await token("bearer", []); + + if (tokenString) { + headerParameters["Authorization"] = `Bearer ${tokenString}`; + } + } + const response = await this.request({ + path: `/library`, + method: 'GET', + headers: headerParameters, + query: queryParameters, + }, initOverrides); + + return new runtime.JSONApiResponse(response, (jsonValue) => jsonValue.map(LibraryResponseDtoFromJSON)); + } + + /** + */ + async getLibraries(initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise> { + const response = await this.getLibrariesRaw(initOverrides); + return await response.value(); + } + + /** + */ + async getLibraryInfoRaw(requestParameters: GetLibraryInfoRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise> { + if (requestParameters.id === null || requestParameters.id === undefined) { + throw new runtime.RequiredError('id','Required parameter requestParameters.id was null or undefined when calling getLibraryInfo.'); + } + + const queryParameters: any = {}; + + const headerParameters: runtime.HTTPHeaders = {}; + + if (this.configuration && this.configuration.apiKey) { + headerParameters["x-api-key"] = this.configuration.apiKey("x-api-key"); // api_key authentication + } + + if (this.configuration && this.configuration.accessToken) { + const token = this.configuration.accessToken; + const tokenString = await token("bearer", []); + + if (tokenString) { + headerParameters["Authorization"] = `Bearer ${tokenString}`; + } + } + const response = await this.request({ + path: `/library/{id}`.replace(`{${"id"}}`, encodeURIComponent(String(requestParameters.id))), + method: 'GET', + headers: headerParameters, + query: queryParameters, + }, initOverrides); + + return new runtime.JSONApiResponse(response, (jsonValue) => LibraryResponseDtoFromJSON(jsonValue)); + } + + /** + */ + async getLibraryInfo(requestParameters: GetLibraryInfoRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise { + const response = await this.getLibraryInfoRaw(requestParameters, initOverrides); + return await response.value(); + } + + /** + */ + async getLibraryStatisticsRaw(requestParameters: GetLibraryStatisticsRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise> { + if (requestParameters.id === null || requestParameters.id === undefined) { + throw new runtime.RequiredError('id','Required parameter requestParameters.id was null or undefined when calling getLibraryStatistics.'); + } + + const queryParameters: any = {}; + + const headerParameters: runtime.HTTPHeaders = {}; + + if (this.configuration && this.configuration.apiKey) { + headerParameters["x-api-key"] = this.configuration.apiKey("x-api-key"); // api_key authentication + } + + if (this.configuration && this.configuration.accessToken) { + const token = this.configuration.accessToken; + const tokenString = await token("bearer", []); + + if (tokenString) { + headerParameters["Authorization"] = `Bearer ${tokenString}`; + } + } + const response = await this.request({ + path: `/library/{id}/statistics`.replace(`{${"id"}}`, encodeURIComponent(String(requestParameters.id))), + method: 'GET', + headers: headerParameters, + query: queryParameters, + }, initOverrides); + + return new runtime.JSONApiResponse(response, (jsonValue) => LibraryStatsResponseDtoFromJSON(jsonValue)); + } + + /** + */ + async getLibraryStatistics(requestParameters: GetLibraryStatisticsRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise { + const response = await this.getLibraryStatisticsRaw(requestParameters, initOverrides); + return await response.value(); + } + + /** + */ + async removeOfflineFilesRaw(requestParameters: RemoveOfflineFilesRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise> { + if (requestParameters.id === null || requestParameters.id === undefined) { + throw new runtime.RequiredError('id','Required parameter requestParameters.id was null or undefined when calling removeOfflineFiles.'); + } + + const queryParameters: any = {}; + + const headerParameters: runtime.HTTPHeaders = {}; + + if (this.configuration && this.configuration.apiKey) { + headerParameters["x-api-key"] = this.configuration.apiKey("x-api-key"); // api_key authentication + } + + if (this.configuration && this.configuration.accessToken) { + const token = this.configuration.accessToken; + const tokenString = await token("bearer", []); + + if (tokenString) { + headerParameters["Authorization"] = `Bearer ${tokenString}`; + } + } + const response = await this.request({ + path: `/library/{id}/removeOffline`.replace(`{${"id"}}`, encodeURIComponent(String(requestParameters.id))), + method: 'POST', + headers: headerParameters, + query: queryParameters, + }, initOverrides); + + return new runtime.VoidApiResponse(response); + } + + /** + */ + async removeOfflineFiles(requestParameters: RemoveOfflineFilesRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise { + await this.removeOfflineFilesRaw(requestParameters, initOverrides); + } + + /** + */ + async scanLibraryRaw(requestParameters: ScanLibraryRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise> { + if (requestParameters.id === null || requestParameters.id === undefined) { + throw new runtime.RequiredError('id','Required parameter requestParameters.id was null or undefined when calling scanLibrary.'); + } + + if (requestParameters.scanLibraryDto === null || requestParameters.scanLibraryDto === undefined) { + throw new runtime.RequiredError('scanLibraryDto','Required parameter requestParameters.scanLibraryDto was null or undefined when calling scanLibrary.'); + } + + const queryParameters: any = {}; + + const headerParameters: runtime.HTTPHeaders = {}; + + headerParameters['Content-Type'] = 'application/json'; + + if (this.configuration && this.configuration.apiKey) { + headerParameters["x-api-key"] = this.configuration.apiKey("x-api-key"); // api_key authentication + } + + if (this.configuration && this.configuration.accessToken) { + const token = this.configuration.accessToken; + const tokenString = await token("bearer", []); + + if (tokenString) { + headerParameters["Authorization"] = `Bearer ${tokenString}`; + } + } + const response = await this.request({ + path: `/library/{id}/scan`.replace(`{${"id"}}`, encodeURIComponent(String(requestParameters.id))), + method: 'POST', + headers: headerParameters, + query: queryParameters, + body: ScanLibraryDtoToJSON(requestParameters.scanLibraryDto), + }, initOverrides); + + return new runtime.VoidApiResponse(response); + } + + /** + */ + async scanLibrary(requestParameters: ScanLibraryRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise { + await this.scanLibraryRaw(requestParameters, initOverrides); + } + + /** + */ + async updateLibraryRaw(requestParameters: UpdateLibraryRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise> { + if (requestParameters.id === null || requestParameters.id === undefined) { + throw new runtime.RequiredError('id','Required parameter requestParameters.id was null or undefined when calling updateLibrary.'); + } + + if (requestParameters.updateLibraryDto === null || requestParameters.updateLibraryDto === undefined) { + throw new runtime.RequiredError('updateLibraryDto','Required parameter requestParameters.updateLibraryDto was null or undefined when calling updateLibrary.'); + } + + const queryParameters: any = {}; + + const headerParameters: runtime.HTTPHeaders = {}; + + headerParameters['Content-Type'] = 'application/json'; + + if (this.configuration && this.configuration.apiKey) { + headerParameters["x-api-key"] = this.configuration.apiKey("x-api-key"); // api_key authentication + } + + if (this.configuration && this.configuration.accessToken) { + const token = this.configuration.accessToken; + const tokenString = await token("bearer", []); + + if (tokenString) { + headerParameters["Authorization"] = `Bearer ${tokenString}`; + } + } + const response = await this.request({ + path: `/library/{id}`.replace(`{${"id"}}`, encodeURIComponent(String(requestParameters.id))), + method: 'PUT', + headers: headerParameters, + query: queryParameters, + body: UpdateLibraryDtoToJSON(requestParameters.updateLibraryDto), + }, initOverrides); + + return new runtime.JSONApiResponse(response, (jsonValue) => LibraryResponseDtoFromJSON(jsonValue)); + } + + /** + */ + async updateLibrary(requestParameters: UpdateLibraryRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise { + const response = await this.updateLibraryRaw(requestParameters, initOverrides); + return await response.value(); + } + +} diff --git a/open-api/typescript-sdk/fetch-client/apis/OAuthApi.ts b/open-api/typescript-sdk/fetch-client/apis/OAuthApi.ts new file mode 100644 index 0000000000..60e30d4e0c --- /dev/null +++ b/open-api/typescript-sdk/fetch-client/apis/OAuthApi.ts @@ -0,0 +1,260 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * Immich + * Immich API + * + * The version of the OpenAPI document: 1.94.1 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + + +import * as runtime from '../runtime'; +import type { + LoginResponseDto, + OAuthAuthorizeResponseDto, + OAuthCallbackDto, + OAuthConfigDto, + OAuthConfigResponseDto, + UserResponseDto, +} from '../models/index'; +import { + LoginResponseDtoFromJSON, + LoginResponseDtoToJSON, + OAuthAuthorizeResponseDtoFromJSON, + OAuthAuthorizeResponseDtoToJSON, + OAuthCallbackDtoFromJSON, + OAuthCallbackDtoToJSON, + OAuthConfigDtoFromJSON, + OAuthConfigDtoToJSON, + OAuthConfigResponseDtoFromJSON, + OAuthConfigResponseDtoToJSON, + UserResponseDtoFromJSON, + UserResponseDtoToJSON, +} from '../models/index'; + +export interface FinishOAuthRequest { + oAuthCallbackDto: OAuthCallbackDto; +} + +export interface GenerateOAuthConfigRequest { + oAuthConfigDto: OAuthConfigDto; +} + +export interface LinkOAuthAccountRequest { + oAuthCallbackDto: OAuthCallbackDto; +} + +export interface StartOAuthRequest { + oAuthConfigDto: OAuthConfigDto; +} + +/** + * + */ +export class OAuthApi extends runtime.BaseAPI { + + /** + */ + async finishOAuthRaw(requestParameters: FinishOAuthRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise> { + if (requestParameters.oAuthCallbackDto === null || requestParameters.oAuthCallbackDto === undefined) { + throw new runtime.RequiredError('oAuthCallbackDto','Required parameter requestParameters.oAuthCallbackDto was null or undefined when calling finishOAuth.'); + } + + const queryParameters: any = {}; + + const headerParameters: runtime.HTTPHeaders = {}; + + headerParameters['Content-Type'] = 'application/json'; + + const response = await this.request({ + path: `/oauth/callback`, + method: 'POST', + headers: headerParameters, + query: queryParameters, + body: OAuthCallbackDtoToJSON(requestParameters.oAuthCallbackDto), + }, initOverrides); + + return new runtime.JSONApiResponse(response, (jsonValue) => LoginResponseDtoFromJSON(jsonValue)); + } + + /** + */ + async finishOAuth(requestParameters: FinishOAuthRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise { + const response = await this.finishOAuthRaw(requestParameters, initOverrides); + return await response.value(); + } + + /** + * @deprecated use feature flags and /oauth/authorize + * @deprecated + */ + async generateOAuthConfigRaw(requestParameters: GenerateOAuthConfigRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise> { + if (requestParameters.oAuthConfigDto === null || requestParameters.oAuthConfigDto === undefined) { + throw new runtime.RequiredError('oAuthConfigDto','Required parameter requestParameters.oAuthConfigDto was null or undefined when calling generateOAuthConfig.'); + } + + const queryParameters: any = {}; + + const headerParameters: runtime.HTTPHeaders = {}; + + headerParameters['Content-Type'] = 'application/json'; + + const response = await this.request({ + path: `/oauth/config`, + method: 'POST', + headers: headerParameters, + query: queryParameters, + body: OAuthConfigDtoToJSON(requestParameters.oAuthConfigDto), + }, initOverrides); + + return new runtime.JSONApiResponse(response, (jsonValue) => OAuthConfigResponseDtoFromJSON(jsonValue)); + } + + /** + * @deprecated use feature flags and /oauth/authorize + * @deprecated + */ + async generateOAuthConfig(requestParameters: GenerateOAuthConfigRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise { + const response = await this.generateOAuthConfigRaw(requestParameters, initOverrides); + return await response.value(); + } + + /** + */ + async linkOAuthAccountRaw(requestParameters: LinkOAuthAccountRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise> { + if (requestParameters.oAuthCallbackDto === null || requestParameters.oAuthCallbackDto === undefined) { + throw new runtime.RequiredError('oAuthCallbackDto','Required parameter requestParameters.oAuthCallbackDto was null or undefined when calling linkOAuthAccount.'); + } + + const queryParameters: any = {}; + + const headerParameters: runtime.HTTPHeaders = {}; + + headerParameters['Content-Type'] = 'application/json'; + + if (this.configuration && this.configuration.apiKey) { + headerParameters["x-api-key"] = this.configuration.apiKey("x-api-key"); // api_key authentication + } + + if (this.configuration && this.configuration.accessToken) { + const token = this.configuration.accessToken; + const tokenString = await token("bearer", []); + + if (tokenString) { + headerParameters["Authorization"] = `Bearer ${tokenString}`; + } + } + const response = await this.request({ + path: `/oauth/link`, + method: 'POST', + headers: headerParameters, + query: queryParameters, + body: OAuthCallbackDtoToJSON(requestParameters.oAuthCallbackDto), + }, initOverrides); + + return new runtime.JSONApiResponse(response, (jsonValue) => UserResponseDtoFromJSON(jsonValue)); + } + + /** + */ + async linkOAuthAccount(requestParameters: LinkOAuthAccountRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise { + const response = await this.linkOAuthAccountRaw(requestParameters, initOverrides); + return await response.value(); + } + + /** + */ + async redirectOAuthToMobileRaw(initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise> { + const queryParameters: any = {}; + + const headerParameters: runtime.HTTPHeaders = {}; + + const response = await this.request({ + path: `/oauth/mobile-redirect`, + method: 'GET', + headers: headerParameters, + query: queryParameters, + }, initOverrides); + + return new runtime.VoidApiResponse(response); + } + + /** + */ + async redirectOAuthToMobile(initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise { + await this.redirectOAuthToMobileRaw(initOverrides); + } + + /** + */ + async startOAuthRaw(requestParameters: StartOAuthRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise> { + if (requestParameters.oAuthConfigDto === null || requestParameters.oAuthConfigDto === undefined) { + throw new runtime.RequiredError('oAuthConfigDto','Required parameter requestParameters.oAuthConfigDto was null or undefined when calling startOAuth.'); + } + + const queryParameters: any = {}; + + const headerParameters: runtime.HTTPHeaders = {}; + + headerParameters['Content-Type'] = 'application/json'; + + const response = await this.request({ + path: `/oauth/authorize`, + method: 'POST', + headers: headerParameters, + query: queryParameters, + body: OAuthConfigDtoToJSON(requestParameters.oAuthConfigDto), + }, initOverrides); + + return new runtime.JSONApiResponse(response, (jsonValue) => OAuthAuthorizeResponseDtoFromJSON(jsonValue)); + } + + /** + */ + async startOAuth(requestParameters: StartOAuthRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise { + const response = await this.startOAuthRaw(requestParameters, initOverrides); + return await response.value(); + } + + /** + */ + async unlinkOAuthAccountRaw(initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise> { + const queryParameters: any = {}; + + const headerParameters: runtime.HTTPHeaders = {}; + + if (this.configuration && this.configuration.apiKey) { + headerParameters["x-api-key"] = this.configuration.apiKey("x-api-key"); // api_key authentication + } + + if (this.configuration && this.configuration.accessToken) { + const token = this.configuration.accessToken; + const tokenString = await token("bearer", []); + + if (tokenString) { + headerParameters["Authorization"] = `Bearer ${tokenString}`; + } + } + const response = await this.request({ + path: `/oauth/unlink`, + method: 'POST', + headers: headerParameters, + query: queryParameters, + }, initOverrides); + + return new runtime.JSONApiResponse(response, (jsonValue) => UserResponseDtoFromJSON(jsonValue)); + } + + /** + */ + async unlinkOAuthAccount(initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise { + const response = await this.unlinkOAuthAccountRaw(initOverrides); + return await response.value(); + } + +} diff --git a/open-api/typescript-sdk/fetch-client/apis/PartnerApi.ts b/open-api/typescript-sdk/fetch-client/apis/PartnerApi.ts new file mode 100644 index 0000000000..8dc49f5d7a --- /dev/null +++ b/open-api/typescript-sdk/fetch-client/apis/PartnerApi.ts @@ -0,0 +1,229 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * Immich + * Immich API + * + * The version of the OpenAPI document: 1.94.1 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + + +import * as runtime from '../runtime'; +import type { + PartnerResponseDto, + UpdatePartnerDto, +} from '../models/index'; +import { + PartnerResponseDtoFromJSON, + PartnerResponseDtoToJSON, + UpdatePartnerDtoFromJSON, + UpdatePartnerDtoToJSON, +} from '../models/index'; + +export interface CreatePartnerRequest { + id: string; +} + +export interface GetPartnersRequest { + direction: GetPartnersDirectionEnum; +} + +export interface RemovePartnerRequest { + id: string; +} + +export interface UpdatePartnerRequest { + id: string; + updatePartnerDto: UpdatePartnerDto; +} + +/** + * + */ +export class PartnerApi extends runtime.BaseAPI { + + /** + */ + async createPartnerRaw(requestParameters: CreatePartnerRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise> { + if (requestParameters.id === null || requestParameters.id === undefined) { + throw new runtime.RequiredError('id','Required parameter requestParameters.id was null or undefined when calling createPartner.'); + } + + const queryParameters: any = {}; + + const headerParameters: runtime.HTTPHeaders = {}; + + if (this.configuration && this.configuration.apiKey) { + headerParameters["x-api-key"] = this.configuration.apiKey("x-api-key"); // api_key authentication + } + + if (this.configuration && this.configuration.accessToken) { + const token = this.configuration.accessToken; + const tokenString = await token("bearer", []); + + if (tokenString) { + headerParameters["Authorization"] = `Bearer ${tokenString}`; + } + } + const response = await this.request({ + path: `/partner/{id}`.replace(`{${"id"}}`, encodeURIComponent(String(requestParameters.id))), + method: 'POST', + headers: headerParameters, + query: queryParameters, + }, initOverrides); + + return new runtime.JSONApiResponse(response, (jsonValue) => PartnerResponseDtoFromJSON(jsonValue)); + } + + /** + */ + async createPartner(requestParameters: CreatePartnerRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise { + const response = await this.createPartnerRaw(requestParameters, initOverrides); + return await response.value(); + } + + /** + */ + async getPartnersRaw(requestParameters: GetPartnersRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise>> { + if (requestParameters.direction === null || requestParameters.direction === undefined) { + throw new runtime.RequiredError('direction','Required parameter requestParameters.direction was null or undefined when calling getPartners.'); + } + + const queryParameters: any = {}; + + if (requestParameters.direction !== undefined) { + queryParameters['direction'] = requestParameters.direction; + } + + const headerParameters: runtime.HTTPHeaders = {}; + + if (this.configuration && this.configuration.apiKey) { + headerParameters["x-api-key"] = this.configuration.apiKey("x-api-key"); // api_key authentication + } + + if (this.configuration && this.configuration.accessToken) { + const token = this.configuration.accessToken; + const tokenString = await token("bearer", []); + + if (tokenString) { + headerParameters["Authorization"] = `Bearer ${tokenString}`; + } + } + const response = await this.request({ + path: `/partner`, + method: 'GET', + headers: headerParameters, + query: queryParameters, + }, initOverrides); + + return new runtime.JSONApiResponse(response, (jsonValue) => jsonValue.map(PartnerResponseDtoFromJSON)); + } + + /** + */ + async getPartners(requestParameters: GetPartnersRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise> { + const response = await this.getPartnersRaw(requestParameters, initOverrides); + return await response.value(); + } + + /** + */ + async removePartnerRaw(requestParameters: RemovePartnerRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise> { + if (requestParameters.id === null || requestParameters.id === undefined) { + throw new runtime.RequiredError('id','Required parameter requestParameters.id was null or undefined when calling removePartner.'); + } + + const queryParameters: any = {}; + + const headerParameters: runtime.HTTPHeaders = {}; + + if (this.configuration && this.configuration.apiKey) { + headerParameters["x-api-key"] = this.configuration.apiKey("x-api-key"); // api_key authentication + } + + if (this.configuration && this.configuration.accessToken) { + const token = this.configuration.accessToken; + const tokenString = await token("bearer", []); + + if (tokenString) { + headerParameters["Authorization"] = `Bearer ${tokenString}`; + } + } + const response = await this.request({ + path: `/partner/{id}`.replace(`{${"id"}}`, encodeURIComponent(String(requestParameters.id))), + method: 'DELETE', + headers: headerParameters, + query: queryParameters, + }, initOverrides); + + return new runtime.VoidApiResponse(response); + } + + /** + */ + async removePartner(requestParameters: RemovePartnerRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise { + await this.removePartnerRaw(requestParameters, initOverrides); + } + + /** + */ + async updatePartnerRaw(requestParameters: UpdatePartnerRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise> { + if (requestParameters.id === null || requestParameters.id === undefined) { + throw new runtime.RequiredError('id','Required parameter requestParameters.id was null or undefined when calling updatePartner.'); + } + + if (requestParameters.updatePartnerDto === null || requestParameters.updatePartnerDto === undefined) { + throw new runtime.RequiredError('updatePartnerDto','Required parameter requestParameters.updatePartnerDto was null or undefined when calling updatePartner.'); + } + + const queryParameters: any = {}; + + const headerParameters: runtime.HTTPHeaders = {}; + + headerParameters['Content-Type'] = 'application/json'; + + if (this.configuration && this.configuration.apiKey) { + headerParameters["x-api-key"] = this.configuration.apiKey("x-api-key"); // api_key authentication + } + + if (this.configuration && this.configuration.accessToken) { + const token = this.configuration.accessToken; + const tokenString = await token("bearer", []); + + if (tokenString) { + headerParameters["Authorization"] = `Bearer ${tokenString}`; + } + } + const response = await this.request({ + path: `/partner/{id}`.replace(`{${"id"}}`, encodeURIComponent(String(requestParameters.id))), + method: 'PUT', + headers: headerParameters, + query: queryParameters, + body: UpdatePartnerDtoToJSON(requestParameters.updatePartnerDto), + }, initOverrides); + + return new runtime.JSONApiResponse(response, (jsonValue) => PartnerResponseDtoFromJSON(jsonValue)); + } + + /** + */ + async updatePartner(requestParameters: UpdatePartnerRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise { + const response = await this.updatePartnerRaw(requestParameters, initOverrides); + return await response.value(); + } + +} + +/** + * @export + */ +export const GetPartnersDirectionEnum = { + By: 'shared-by', + With: 'shared-with' +} as const; +export type GetPartnersDirectionEnum = typeof GetPartnersDirectionEnum[keyof typeof GetPartnersDirectionEnum]; diff --git a/open-api/typescript-sdk/fetch-client/apis/PersonApi.ts b/open-api/typescript-sdk/fetch-client/apis/PersonApi.ts new file mode 100644 index 0000000000..d56b639639 --- /dev/null +++ b/open-api/typescript-sdk/fetch-client/apis/PersonApi.ts @@ -0,0 +1,513 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * Immich + * Immich API + * + * The version of the OpenAPI document: 1.94.1 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + + +import * as runtime from '../runtime'; +import type { + AssetFaceUpdateDto, + AssetResponseDto, + BulkIdResponseDto, + MergePersonDto, + PeopleResponseDto, + PeopleUpdateDto, + PersonResponseDto, + PersonStatisticsResponseDto, + PersonUpdateDto, +} from '../models/index'; +import { + AssetFaceUpdateDtoFromJSON, + AssetFaceUpdateDtoToJSON, + AssetResponseDtoFromJSON, + AssetResponseDtoToJSON, + BulkIdResponseDtoFromJSON, + BulkIdResponseDtoToJSON, + MergePersonDtoFromJSON, + MergePersonDtoToJSON, + PeopleResponseDtoFromJSON, + PeopleResponseDtoToJSON, + PeopleUpdateDtoFromJSON, + PeopleUpdateDtoToJSON, + PersonResponseDtoFromJSON, + PersonResponseDtoToJSON, + PersonStatisticsResponseDtoFromJSON, + PersonStatisticsResponseDtoToJSON, + PersonUpdateDtoFromJSON, + PersonUpdateDtoToJSON, +} from '../models/index'; + +export interface GetAllPeopleRequest { + withHidden?: boolean; +} + +export interface GetPersonRequest { + id: string; +} + +export interface GetPersonAssetsRequest { + id: string; +} + +export interface GetPersonStatisticsRequest { + id: string; +} + +export interface GetPersonThumbnailRequest { + id: string; +} + +export interface MergePersonRequest { + id: string; + mergePersonDto: MergePersonDto; +} + +export interface ReassignFacesRequest { + id: string; + assetFaceUpdateDto: AssetFaceUpdateDto; +} + +export interface UpdatePeopleRequest { + peopleUpdateDto: PeopleUpdateDto; +} + +export interface UpdatePersonRequest { + id: string; + personUpdateDto: PersonUpdateDto; +} + +/** + * + */ +export class PersonApi extends runtime.BaseAPI { + + /** + */ + async createPersonRaw(initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise> { + const queryParameters: any = {}; + + const headerParameters: runtime.HTTPHeaders = {}; + + if (this.configuration && this.configuration.apiKey) { + headerParameters["x-api-key"] = this.configuration.apiKey("x-api-key"); // api_key authentication + } + + if (this.configuration && this.configuration.accessToken) { + const token = this.configuration.accessToken; + const tokenString = await token("bearer", []); + + if (tokenString) { + headerParameters["Authorization"] = `Bearer ${tokenString}`; + } + } + const response = await this.request({ + path: `/person`, + method: 'POST', + headers: headerParameters, + query: queryParameters, + }, initOverrides); + + return new runtime.JSONApiResponse(response, (jsonValue) => PersonResponseDtoFromJSON(jsonValue)); + } + + /** + */ + async createPerson(initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise { + const response = await this.createPersonRaw(initOverrides); + return await response.value(); + } + + /** + */ + async getAllPeopleRaw(requestParameters: GetAllPeopleRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise> { + const queryParameters: any = {}; + + if (requestParameters.withHidden !== undefined) { + queryParameters['withHidden'] = requestParameters.withHidden; + } + + const headerParameters: runtime.HTTPHeaders = {}; + + if (this.configuration && this.configuration.apiKey) { + headerParameters["x-api-key"] = this.configuration.apiKey("x-api-key"); // api_key authentication + } + + if (this.configuration && this.configuration.accessToken) { + const token = this.configuration.accessToken; + const tokenString = await token("bearer", []); + + if (tokenString) { + headerParameters["Authorization"] = `Bearer ${tokenString}`; + } + } + const response = await this.request({ + path: `/person`, + method: 'GET', + headers: headerParameters, + query: queryParameters, + }, initOverrides); + + return new runtime.JSONApiResponse(response, (jsonValue) => PeopleResponseDtoFromJSON(jsonValue)); + } + + /** + */ + async getAllPeople(requestParameters: GetAllPeopleRequest = {}, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise { + const response = await this.getAllPeopleRaw(requestParameters, initOverrides); + return await response.value(); + } + + /** + */ + async getPersonRaw(requestParameters: GetPersonRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise> { + if (requestParameters.id === null || requestParameters.id === undefined) { + throw new runtime.RequiredError('id','Required parameter requestParameters.id was null or undefined when calling getPerson.'); + } + + const queryParameters: any = {}; + + const headerParameters: runtime.HTTPHeaders = {}; + + if (this.configuration && this.configuration.apiKey) { + headerParameters["x-api-key"] = this.configuration.apiKey("x-api-key"); // api_key authentication + } + + if (this.configuration && this.configuration.accessToken) { + const token = this.configuration.accessToken; + const tokenString = await token("bearer", []); + + if (tokenString) { + headerParameters["Authorization"] = `Bearer ${tokenString}`; + } + } + const response = await this.request({ + path: `/person/{id}`.replace(`{${"id"}}`, encodeURIComponent(String(requestParameters.id))), + method: 'GET', + headers: headerParameters, + query: queryParameters, + }, initOverrides); + + return new runtime.JSONApiResponse(response, (jsonValue) => PersonResponseDtoFromJSON(jsonValue)); + } + + /** + */ + async getPerson(requestParameters: GetPersonRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise { + const response = await this.getPersonRaw(requestParameters, initOverrides); + return await response.value(); + } + + /** + */ + async getPersonAssetsRaw(requestParameters: GetPersonAssetsRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise>> { + if (requestParameters.id === null || requestParameters.id === undefined) { + throw new runtime.RequiredError('id','Required parameter requestParameters.id was null or undefined when calling getPersonAssets.'); + } + + const queryParameters: any = {}; + + const headerParameters: runtime.HTTPHeaders = {}; + + if (this.configuration && this.configuration.apiKey) { + headerParameters["x-api-key"] = this.configuration.apiKey("x-api-key"); // api_key authentication + } + + if (this.configuration && this.configuration.accessToken) { + const token = this.configuration.accessToken; + const tokenString = await token("bearer", []); + + if (tokenString) { + headerParameters["Authorization"] = `Bearer ${tokenString}`; + } + } + const response = await this.request({ + path: `/person/{id}/assets`.replace(`{${"id"}}`, encodeURIComponent(String(requestParameters.id))), + method: 'GET', + headers: headerParameters, + query: queryParameters, + }, initOverrides); + + return new runtime.JSONApiResponse(response, (jsonValue) => jsonValue.map(AssetResponseDtoFromJSON)); + } + + /** + */ + async getPersonAssets(requestParameters: GetPersonAssetsRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise> { + const response = await this.getPersonAssetsRaw(requestParameters, initOverrides); + return await response.value(); + } + + /** + */ + async getPersonStatisticsRaw(requestParameters: GetPersonStatisticsRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise> { + if (requestParameters.id === null || requestParameters.id === undefined) { + throw new runtime.RequiredError('id','Required parameter requestParameters.id was null or undefined when calling getPersonStatistics.'); + } + + const queryParameters: any = {}; + + const headerParameters: runtime.HTTPHeaders = {}; + + if (this.configuration && this.configuration.apiKey) { + headerParameters["x-api-key"] = this.configuration.apiKey("x-api-key"); // api_key authentication + } + + if (this.configuration && this.configuration.accessToken) { + const token = this.configuration.accessToken; + const tokenString = await token("bearer", []); + + if (tokenString) { + headerParameters["Authorization"] = `Bearer ${tokenString}`; + } + } + const response = await this.request({ + path: `/person/{id}/statistics`.replace(`{${"id"}}`, encodeURIComponent(String(requestParameters.id))), + method: 'GET', + headers: headerParameters, + query: queryParameters, + }, initOverrides); + + return new runtime.JSONApiResponse(response, (jsonValue) => PersonStatisticsResponseDtoFromJSON(jsonValue)); + } + + /** + */ + async getPersonStatistics(requestParameters: GetPersonStatisticsRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise { + const response = await this.getPersonStatisticsRaw(requestParameters, initOverrides); + return await response.value(); + } + + /** + */ + async getPersonThumbnailRaw(requestParameters: GetPersonThumbnailRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise> { + if (requestParameters.id === null || requestParameters.id === undefined) { + throw new runtime.RequiredError('id','Required parameter requestParameters.id was null or undefined when calling getPersonThumbnail.'); + } + + const queryParameters: any = {}; + + const headerParameters: runtime.HTTPHeaders = {}; + + if (this.configuration && this.configuration.apiKey) { + headerParameters["x-api-key"] = this.configuration.apiKey("x-api-key"); // api_key authentication + } + + if (this.configuration && this.configuration.accessToken) { + const token = this.configuration.accessToken; + const tokenString = await token("bearer", []); + + if (tokenString) { + headerParameters["Authorization"] = `Bearer ${tokenString}`; + } + } + const response = await this.request({ + path: `/person/{id}/thumbnail`.replace(`{${"id"}}`, encodeURIComponent(String(requestParameters.id))), + method: 'GET', + headers: headerParameters, + query: queryParameters, + }, initOverrides); + + return new runtime.BlobApiResponse(response); + } + + /** + */ + async getPersonThumbnail(requestParameters: GetPersonThumbnailRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise { + const response = await this.getPersonThumbnailRaw(requestParameters, initOverrides); + return await response.value(); + } + + /** + */ + async mergePersonRaw(requestParameters: MergePersonRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise>> { + if (requestParameters.id === null || requestParameters.id === undefined) { + throw new runtime.RequiredError('id','Required parameter requestParameters.id was null or undefined when calling mergePerson.'); + } + + if (requestParameters.mergePersonDto === null || requestParameters.mergePersonDto === undefined) { + throw new runtime.RequiredError('mergePersonDto','Required parameter requestParameters.mergePersonDto was null or undefined when calling mergePerson.'); + } + + const queryParameters: any = {}; + + const headerParameters: runtime.HTTPHeaders = {}; + + headerParameters['Content-Type'] = 'application/json'; + + if (this.configuration && this.configuration.apiKey) { + headerParameters["x-api-key"] = this.configuration.apiKey("x-api-key"); // api_key authentication + } + + if (this.configuration && this.configuration.accessToken) { + const token = this.configuration.accessToken; + const tokenString = await token("bearer", []); + + if (tokenString) { + headerParameters["Authorization"] = `Bearer ${tokenString}`; + } + } + const response = await this.request({ + path: `/person/{id}/merge`.replace(`{${"id"}}`, encodeURIComponent(String(requestParameters.id))), + method: 'POST', + headers: headerParameters, + query: queryParameters, + body: MergePersonDtoToJSON(requestParameters.mergePersonDto), + }, initOverrides); + + return new runtime.JSONApiResponse(response, (jsonValue) => jsonValue.map(BulkIdResponseDtoFromJSON)); + } + + /** + */ + async mergePerson(requestParameters: MergePersonRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise> { + const response = await this.mergePersonRaw(requestParameters, initOverrides); + return await response.value(); + } + + /** + */ + async reassignFacesRaw(requestParameters: ReassignFacesRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise>> { + if (requestParameters.id === null || requestParameters.id === undefined) { + throw new runtime.RequiredError('id','Required parameter requestParameters.id was null or undefined when calling reassignFaces.'); + } + + if (requestParameters.assetFaceUpdateDto === null || requestParameters.assetFaceUpdateDto === undefined) { + throw new runtime.RequiredError('assetFaceUpdateDto','Required parameter requestParameters.assetFaceUpdateDto was null or undefined when calling reassignFaces.'); + } + + const queryParameters: any = {}; + + const headerParameters: runtime.HTTPHeaders = {}; + + headerParameters['Content-Type'] = 'application/json'; + + if (this.configuration && this.configuration.apiKey) { + headerParameters["x-api-key"] = this.configuration.apiKey("x-api-key"); // api_key authentication + } + + if (this.configuration && this.configuration.accessToken) { + const token = this.configuration.accessToken; + const tokenString = await token("bearer", []); + + if (tokenString) { + headerParameters["Authorization"] = `Bearer ${tokenString}`; + } + } + const response = await this.request({ + path: `/person/{id}/reassign`.replace(`{${"id"}}`, encodeURIComponent(String(requestParameters.id))), + method: 'PUT', + headers: headerParameters, + query: queryParameters, + body: AssetFaceUpdateDtoToJSON(requestParameters.assetFaceUpdateDto), + }, initOverrides); + + return new runtime.JSONApiResponse(response, (jsonValue) => jsonValue.map(PersonResponseDtoFromJSON)); + } + + /** + */ + async reassignFaces(requestParameters: ReassignFacesRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise> { + const response = await this.reassignFacesRaw(requestParameters, initOverrides); + return await response.value(); + } + + /** + */ + async updatePeopleRaw(requestParameters: UpdatePeopleRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise>> { + if (requestParameters.peopleUpdateDto === null || requestParameters.peopleUpdateDto === undefined) { + throw new runtime.RequiredError('peopleUpdateDto','Required parameter requestParameters.peopleUpdateDto was null or undefined when calling updatePeople.'); + } + + const queryParameters: any = {}; + + const headerParameters: runtime.HTTPHeaders = {}; + + headerParameters['Content-Type'] = 'application/json'; + + if (this.configuration && this.configuration.apiKey) { + headerParameters["x-api-key"] = this.configuration.apiKey("x-api-key"); // api_key authentication + } + + if (this.configuration && this.configuration.accessToken) { + const token = this.configuration.accessToken; + const tokenString = await token("bearer", []); + + if (tokenString) { + headerParameters["Authorization"] = `Bearer ${tokenString}`; + } + } + const response = await this.request({ + path: `/person`, + method: 'PUT', + headers: headerParameters, + query: queryParameters, + body: PeopleUpdateDtoToJSON(requestParameters.peopleUpdateDto), + }, initOverrides); + + return new runtime.JSONApiResponse(response, (jsonValue) => jsonValue.map(BulkIdResponseDtoFromJSON)); + } + + /** + */ + async updatePeople(requestParameters: UpdatePeopleRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise> { + const response = await this.updatePeopleRaw(requestParameters, initOverrides); + return await response.value(); + } + + /** + */ + async updatePersonRaw(requestParameters: UpdatePersonRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise> { + if (requestParameters.id === null || requestParameters.id === undefined) { + throw new runtime.RequiredError('id','Required parameter requestParameters.id was null or undefined when calling updatePerson.'); + } + + if (requestParameters.personUpdateDto === null || requestParameters.personUpdateDto === undefined) { + throw new runtime.RequiredError('personUpdateDto','Required parameter requestParameters.personUpdateDto was null or undefined when calling updatePerson.'); + } + + const queryParameters: any = {}; + + const headerParameters: runtime.HTTPHeaders = {}; + + headerParameters['Content-Type'] = 'application/json'; + + if (this.configuration && this.configuration.apiKey) { + headerParameters["x-api-key"] = this.configuration.apiKey("x-api-key"); // api_key authentication + } + + if (this.configuration && this.configuration.accessToken) { + const token = this.configuration.accessToken; + const tokenString = await token("bearer", []); + + if (tokenString) { + headerParameters["Authorization"] = `Bearer ${tokenString}`; + } + } + const response = await this.request({ + path: `/person/{id}`.replace(`{${"id"}}`, encodeURIComponent(String(requestParameters.id))), + method: 'PUT', + headers: headerParameters, + query: queryParameters, + body: PersonUpdateDtoToJSON(requestParameters.personUpdateDto), + }, initOverrides); + + return new runtime.JSONApiResponse(response, (jsonValue) => PersonResponseDtoFromJSON(jsonValue)); + } + + /** + */ + async updatePerson(requestParameters: UpdatePersonRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise { + const response = await this.updatePersonRaw(requestParameters, initOverrides); + return await response.value(); + } + +} diff --git a/open-api/typescript-sdk/fetch-client/apis/SearchApi.ts b/open-api/typescript-sdk/fetch-client/apis/SearchApi.ts new file mode 100644 index 0000000000..616501b08f --- /dev/null +++ b/open-api/typescript-sdk/fetch-client/apis/SearchApi.ts @@ -0,0 +1,215 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * Immich + * Immich API + * + * The version of the OpenAPI document: 1.94.1 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + + +import * as runtime from '../runtime'; +import type { + PersonResponseDto, + SearchExploreResponseDto, + SearchResponseDto, +} from '../models/index'; +import { + PersonResponseDtoFromJSON, + PersonResponseDtoToJSON, + SearchExploreResponseDtoFromJSON, + SearchExploreResponseDtoToJSON, + SearchResponseDtoFromJSON, + SearchResponseDtoToJSON, +} from '../models/index'; + +export interface SearchRequest { + clip?: boolean; + motion?: boolean; + q?: string; + query?: string; + recent?: boolean; + smart?: boolean; + type?: SearchTypeEnum; + withArchived?: boolean; +} + +export interface SearchPersonRequest { + name: string; + withHidden?: boolean; +} + +/** + * + */ +export class SearchApi extends runtime.BaseAPI { + + /** + */ + async getExploreDataRaw(initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise>> { + const queryParameters: any = {}; + + const headerParameters: runtime.HTTPHeaders = {}; + + if (this.configuration && this.configuration.apiKey) { + headerParameters["x-api-key"] = this.configuration.apiKey("x-api-key"); // api_key authentication + } + + if (this.configuration && this.configuration.accessToken) { + const token = this.configuration.accessToken; + const tokenString = await token("bearer", []); + + if (tokenString) { + headerParameters["Authorization"] = `Bearer ${tokenString}`; + } + } + const response = await this.request({ + path: `/search/explore`, + method: 'GET', + headers: headerParameters, + query: queryParameters, + }, initOverrides); + + return new runtime.JSONApiResponse(response, (jsonValue) => jsonValue.map(SearchExploreResponseDtoFromJSON)); + } + + /** + */ + async getExploreData(initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise> { + const response = await this.getExploreDataRaw(initOverrides); + return await response.value(); + } + + /** + */ + async searchRaw(requestParameters: SearchRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise> { + const queryParameters: any = {}; + + if (requestParameters.clip !== undefined) { + queryParameters['clip'] = requestParameters.clip; + } + + if (requestParameters.motion !== undefined) { + queryParameters['motion'] = requestParameters.motion; + } + + if (requestParameters.q !== undefined) { + queryParameters['q'] = requestParameters.q; + } + + if (requestParameters.query !== undefined) { + queryParameters['query'] = requestParameters.query; + } + + if (requestParameters.recent !== undefined) { + queryParameters['recent'] = requestParameters.recent; + } + + if (requestParameters.smart !== undefined) { + queryParameters['smart'] = requestParameters.smart; + } + + if (requestParameters.type !== undefined) { + queryParameters['type'] = requestParameters.type; + } + + if (requestParameters.withArchived !== undefined) { + queryParameters['withArchived'] = requestParameters.withArchived; + } + + const headerParameters: runtime.HTTPHeaders = {}; + + if (this.configuration && this.configuration.apiKey) { + headerParameters["x-api-key"] = this.configuration.apiKey("x-api-key"); // api_key authentication + } + + if (this.configuration && this.configuration.accessToken) { + const token = this.configuration.accessToken; + const tokenString = await token("bearer", []); + + if (tokenString) { + headerParameters["Authorization"] = `Bearer ${tokenString}`; + } + } + const response = await this.request({ + path: `/search`, + method: 'GET', + headers: headerParameters, + query: queryParameters, + }, initOverrides); + + return new runtime.JSONApiResponse(response, (jsonValue) => SearchResponseDtoFromJSON(jsonValue)); + } + + /** + */ + async search(requestParameters: SearchRequest = {}, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise { + const response = await this.searchRaw(requestParameters, initOverrides); + return await response.value(); + } + + /** + */ + async searchPersonRaw(requestParameters: SearchPersonRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise>> { + if (requestParameters.name === null || requestParameters.name === undefined) { + throw new runtime.RequiredError('name','Required parameter requestParameters.name was null or undefined when calling searchPerson.'); + } + + const queryParameters: any = {}; + + if (requestParameters.name !== undefined) { + queryParameters['name'] = requestParameters.name; + } + + if (requestParameters.withHidden !== undefined) { + queryParameters['withHidden'] = requestParameters.withHidden; + } + + const headerParameters: runtime.HTTPHeaders = {}; + + if (this.configuration && this.configuration.apiKey) { + headerParameters["x-api-key"] = this.configuration.apiKey("x-api-key"); // api_key authentication + } + + if (this.configuration && this.configuration.accessToken) { + const token = this.configuration.accessToken; + const tokenString = await token("bearer", []); + + if (tokenString) { + headerParameters["Authorization"] = `Bearer ${tokenString}`; + } + } + const response = await this.request({ + path: `/search/person`, + method: 'GET', + headers: headerParameters, + query: queryParameters, + }, initOverrides); + + return new runtime.JSONApiResponse(response, (jsonValue) => jsonValue.map(PersonResponseDtoFromJSON)); + } + + /** + */ + async searchPerson(requestParameters: SearchPersonRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise> { + const response = await this.searchPersonRaw(requestParameters, initOverrides); + return await response.value(); + } + +} + +/** + * @export + */ +export const SearchTypeEnum = { + Image: 'IMAGE', + Video: 'VIDEO', + Audio: 'AUDIO', + Other: 'OTHER' +} as const; +export type SearchTypeEnum = typeof SearchTypeEnum[keyof typeof SearchTypeEnum]; diff --git a/open-api/typescript-sdk/fetch-client/apis/ServerInfoApi.ts b/open-api/typescript-sdk/fetch-client/apis/ServerInfoApi.ts new file mode 100644 index 0000000000..2cff067147 --- /dev/null +++ b/open-api/typescript-sdk/fetch-client/apis/ServerInfoApi.ts @@ -0,0 +1,302 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * Immich + * Immich API + * + * The version of the OpenAPI document: 1.94.1 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + + +import * as runtime from '../runtime'; +import type { + ServerConfigDto, + ServerFeaturesDto, + ServerInfoResponseDto, + ServerMediaTypesResponseDto, + ServerPingResponse, + ServerStatsResponseDto, + ServerThemeDto, + ServerVersionResponseDto, +} from '../models/index'; +import { + ServerConfigDtoFromJSON, + ServerConfigDtoToJSON, + ServerFeaturesDtoFromJSON, + ServerFeaturesDtoToJSON, + ServerInfoResponseDtoFromJSON, + ServerInfoResponseDtoToJSON, + ServerMediaTypesResponseDtoFromJSON, + ServerMediaTypesResponseDtoToJSON, + ServerPingResponseFromJSON, + ServerPingResponseToJSON, + ServerStatsResponseDtoFromJSON, + ServerStatsResponseDtoToJSON, + ServerThemeDtoFromJSON, + ServerThemeDtoToJSON, + ServerVersionResponseDtoFromJSON, + ServerVersionResponseDtoToJSON, +} from '../models/index'; + +/** + * + */ +export class ServerInfoApi extends runtime.BaseAPI { + + /** + */ + async getServerConfigRaw(initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise> { + const queryParameters: any = {}; + + const headerParameters: runtime.HTTPHeaders = {}; + + const response = await this.request({ + path: `/server-info/config`, + method: 'GET', + headers: headerParameters, + query: queryParameters, + }, initOverrides); + + return new runtime.JSONApiResponse(response, (jsonValue) => ServerConfigDtoFromJSON(jsonValue)); + } + + /** + */ + async getServerConfig(initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise { + const response = await this.getServerConfigRaw(initOverrides); + return await response.value(); + } + + /** + */ + async getServerFeaturesRaw(initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise> { + const queryParameters: any = {}; + + const headerParameters: runtime.HTTPHeaders = {}; + + const response = await this.request({ + path: `/server-info/features`, + method: 'GET', + headers: headerParameters, + query: queryParameters, + }, initOverrides); + + return new runtime.JSONApiResponse(response, (jsonValue) => ServerFeaturesDtoFromJSON(jsonValue)); + } + + /** + */ + async getServerFeatures(initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise { + const response = await this.getServerFeaturesRaw(initOverrides); + return await response.value(); + } + + /** + */ + async getServerInfoRaw(initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise> { + const queryParameters: any = {}; + + const headerParameters: runtime.HTTPHeaders = {}; + + if (this.configuration && this.configuration.apiKey) { + headerParameters["x-api-key"] = this.configuration.apiKey("x-api-key"); // api_key authentication + } + + if (this.configuration && this.configuration.accessToken) { + const token = this.configuration.accessToken; + const tokenString = await token("bearer", []); + + if (tokenString) { + headerParameters["Authorization"] = `Bearer ${tokenString}`; + } + } + const response = await this.request({ + path: `/server-info`, + method: 'GET', + headers: headerParameters, + query: queryParameters, + }, initOverrides); + + return new runtime.JSONApiResponse(response, (jsonValue) => ServerInfoResponseDtoFromJSON(jsonValue)); + } + + /** + */ + async getServerInfo(initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise { + const response = await this.getServerInfoRaw(initOverrides); + return await response.value(); + } + + /** + */ + async getServerStatisticsRaw(initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise> { + const queryParameters: any = {}; + + const headerParameters: runtime.HTTPHeaders = {}; + + if (this.configuration && this.configuration.apiKey) { + headerParameters["x-api-key"] = this.configuration.apiKey("x-api-key"); // api_key authentication + } + + if (this.configuration && this.configuration.accessToken) { + const token = this.configuration.accessToken; + const tokenString = await token("bearer", []); + + if (tokenString) { + headerParameters["Authorization"] = `Bearer ${tokenString}`; + } + } + const response = await this.request({ + path: `/server-info/statistics`, + method: 'GET', + headers: headerParameters, + query: queryParameters, + }, initOverrides); + + return new runtime.JSONApiResponse(response, (jsonValue) => ServerStatsResponseDtoFromJSON(jsonValue)); + } + + /** + */ + async getServerStatistics(initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise { + const response = await this.getServerStatisticsRaw(initOverrides); + return await response.value(); + } + + /** + */ + async getServerVersionRaw(initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise> { + const queryParameters: any = {}; + + const headerParameters: runtime.HTTPHeaders = {}; + + const response = await this.request({ + path: `/server-info/version`, + method: 'GET', + headers: headerParameters, + query: queryParameters, + }, initOverrides); + + return new runtime.JSONApiResponse(response, (jsonValue) => ServerVersionResponseDtoFromJSON(jsonValue)); + } + + /** + */ + async getServerVersion(initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise { + const response = await this.getServerVersionRaw(initOverrides); + return await response.value(); + } + + /** + */ + async getSupportedMediaTypesRaw(initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise> { + const queryParameters: any = {}; + + const headerParameters: runtime.HTTPHeaders = {}; + + const response = await this.request({ + path: `/server-info/media-types`, + method: 'GET', + headers: headerParameters, + query: queryParameters, + }, initOverrides); + + return new runtime.JSONApiResponse(response, (jsonValue) => ServerMediaTypesResponseDtoFromJSON(jsonValue)); + } + + /** + */ + async getSupportedMediaTypes(initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise { + const response = await this.getSupportedMediaTypesRaw(initOverrides); + return await response.value(); + } + + /** + */ + async getThemeRaw(initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise> { + const queryParameters: any = {}; + + const headerParameters: runtime.HTTPHeaders = {}; + + const response = await this.request({ + path: `/server-info/theme`, + method: 'GET', + headers: headerParameters, + query: queryParameters, + }, initOverrides); + + return new runtime.JSONApiResponse(response, (jsonValue) => ServerThemeDtoFromJSON(jsonValue)); + } + + /** + */ + async getTheme(initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise { + const response = await this.getThemeRaw(initOverrides); + return await response.value(); + } + + /** + */ + async pingServerRaw(initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise> { + const queryParameters: any = {}; + + const headerParameters: runtime.HTTPHeaders = {}; + + const response = await this.request({ + path: `/server-info/ping`, + method: 'GET', + headers: headerParameters, + query: queryParameters, + }, initOverrides); + + return new runtime.JSONApiResponse(response, (jsonValue) => ServerPingResponseFromJSON(jsonValue)); + } + + /** + */ + async pingServer(initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise { + const response = await this.pingServerRaw(initOverrides); + return await response.value(); + } + + /** + */ + async setAdminOnboardingRaw(initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise> { + const queryParameters: any = {}; + + const headerParameters: runtime.HTTPHeaders = {}; + + if (this.configuration && this.configuration.apiKey) { + headerParameters["x-api-key"] = this.configuration.apiKey("x-api-key"); // api_key authentication + } + + if (this.configuration && this.configuration.accessToken) { + const token = this.configuration.accessToken; + const tokenString = await token("bearer", []); + + if (tokenString) { + headerParameters["Authorization"] = `Bearer ${tokenString}`; + } + } + const response = await this.request({ + path: `/server-info/admin-onboarding`, + method: 'POST', + headers: headerParameters, + query: queryParameters, + }, initOverrides); + + return new runtime.VoidApiResponse(response); + } + + /** + */ + async setAdminOnboarding(initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise { + await this.setAdminOnboardingRaw(initOverrides); + } + +} diff --git a/open-api/typescript-sdk/fetch-client/apis/SharedLinkApi.ts b/open-api/typescript-sdk/fetch-client/apis/SharedLinkApi.ts new file mode 100644 index 0000000000..c3ba1388a9 --- /dev/null +++ b/open-api/typescript-sdk/fetch-client/apis/SharedLinkApi.ts @@ -0,0 +1,432 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * Immich + * Immich API + * + * The version of the OpenAPI document: 1.94.1 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + + +import * as runtime from '../runtime'; +import type { + AssetIdsDto, + AssetIdsResponseDto, + SharedLinkCreateDto, + SharedLinkEditDto, + SharedLinkResponseDto, +} from '../models/index'; +import { + AssetIdsDtoFromJSON, + AssetIdsDtoToJSON, + AssetIdsResponseDtoFromJSON, + AssetIdsResponseDtoToJSON, + SharedLinkCreateDtoFromJSON, + SharedLinkCreateDtoToJSON, + SharedLinkEditDtoFromJSON, + SharedLinkEditDtoToJSON, + SharedLinkResponseDtoFromJSON, + SharedLinkResponseDtoToJSON, +} from '../models/index'; + +export interface AddSharedLinkAssetsRequest { + id: string; + assetIdsDto: AssetIdsDto; + key?: string; +} + +export interface CreateSharedLinkRequest { + sharedLinkCreateDto: SharedLinkCreateDto; +} + +export interface GetMySharedLinkRequest { + key?: string; + password?: string; + token?: string; +} + +export interface GetSharedLinkByIdRequest { + id: string; +} + +export interface RemoveSharedLinkRequest { + id: string; +} + +export interface RemoveSharedLinkAssetsRequest { + id: string; + assetIdsDto: AssetIdsDto; + key?: string; +} + +export interface UpdateSharedLinkRequest { + id: string; + sharedLinkEditDto: SharedLinkEditDto; +} + +/** + * + */ +export class SharedLinkApi extends runtime.BaseAPI { + + /** + */ + async addSharedLinkAssetsRaw(requestParameters: AddSharedLinkAssetsRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise>> { + if (requestParameters.id === null || requestParameters.id === undefined) { + throw new runtime.RequiredError('id','Required parameter requestParameters.id was null or undefined when calling addSharedLinkAssets.'); + } + + if (requestParameters.assetIdsDto === null || requestParameters.assetIdsDto === undefined) { + throw new runtime.RequiredError('assetIdsDto','Required parameter requestParameters.assetIdsDto was null or undefined when calling addSharedLinkAssets.'); + } + + const queryParameters: any = {}; + + if (requestParameters.key !== undefined) { + queryParameters['key'] = requestParameters.key; + } + + const headerParameters: runtime.HTTPHeaders = {}; + + headerParameters['Content-Type'] = 'application/json'; + + if (this.configuration && this.configuration.apiKey) { + headerParameters["x-api-key"] = this.configuration.apiKey("x-api-key"); // api_key authentication + } + + if (this.configuration && this.configuration.accessToken) { + const token = this.configuration.accessToken; + const tokenString = await token("bearer", []); + + if (tokenString) { + headerParameters["Authorization"] = `Bearer ${tokenString}`; + } + } + const response = await this.request({ + path: `/shared-link/{id}/assets`.replace(`{${"id"}}`, encodeURIComponent(String(requestParameters.id))), + method: 'PUT', + headers: headerParameters, + query: queryParameters, + body: AssetIdsDtoToJSON(requestParameters.assetIdsDto), + }, initOverrides); + + return new runtime.JSONApiResponse(response, (jsonValue) => jsonValue.map(AssetIdsResponseDtoFromJSON)); + } + + /** + */ + async addSharedLinkAssets(requestParameters: AddSharedLinkAssetsRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise> { + const response = await this.addSharedLinkAssetsRaw(requestParameters, initOverrides); + return await response.value(); + } + + /** + */ + async createSharedLinkRaw(requestParameters: CreateSharedLinkRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise> { + if (requestParameters.sharedLinkCreateDto === null || requestParameters.sharedLinkCreateDto === undefined) { + throw new runtime.RequiredError('sharedLinkCreateDto','Required parameter requestParameters.sharedLinkCreateDto was null or undefined when calling createSharedLink.'); + } + + const queryParameters: any = {}; + + const headerParameters: runtime.HTTPHeaders = {}; + + headerParameters['Content-Type'] = 'application/json'; + + if (this.configuration && this.configuration.apiKey) { + headerParameters["x-api-key"] = this.configuration.apiKey("x-api-key"); // api_key authentication + } + + if (this.configuration && this.configuration.accessToken) { + const token = this.configuration.accessToken; + const tokenString = await token("bearer", []); + + if (tokenString) { + headerParameters["Authorization"] = `Bearer ${tokenString}`; + } + } + const response = await this.request({ + path: `/shared-link`, + method: 'POST', + headers: headerParameters, + query: queryParameters, + body: SharedLinkCreateDtoToJSON(requestParameters.sharedLinkCreateDto), + }, initOverrides); + + return new runtime.JSONApiResponse(response, (jsonValue) => SharedLinkResponseDtoFromJSON(jsonValue)); + } + + /** + */ + async createSharedLink(requestParameters: CreateSharedLinkRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise { + const response = await this.createSharedLinkRaw(requestParameters, initOverrides); + return await response.value(); + } + + /** + */ + async getAllSharedLinksRaw(initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise>> { + const queryParameters: any = {}; + + const headerParameters: runtime.HTTPHeaders = {}; + + if (this.configuration && this.configuration.apiKey) { + headerParameters["x-api-key"] = this.configuration.apiKey("x-api-key"); // api_key authentication + } + + if (this.configuration && this.configuration.accessToken) { + const token = this.configuration.accessToken; + const tokenString = await token("bearer", []); + + if (tokenString) { + headerParameters["Authorization"] = `Bearer ${tokenString}`; + } + } + const response = await this.request({ + path: `/shared-link`, + method: 'GET', + headers: headerParameters, + query: queryParameters, + }, initOverrides); + + return new runtime.JSONApiResponse(response, (jsonValue) => jsonValue.map(SharedLinkResponseDtoFromJSON)); + } + + /** + */ + async getAllSharedLinks(initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise> { + const response = await this.getAllSharedLinksRaw(initOverrides); + return await response.value(); + } + + /** + */ + async getMySharedLinkRaw(requestParameters: GetMySharedLinkRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise> { + const queryParameters: any = {}; + + if (requestParameters.key !== undefined) { + queryParameters['key'] = requestParameters.key; + } + + if (requestParameters.password !== undefined) { + queryParameters['password'] = requestParameters.password; + } + + if (requestParameters.token !== undefined) { + queryParameters['token'] = requestParameters.token; + } + + const headerParameters: runtime.HTTPHeaders = {}; + + if (this.configuration && this.configuration.apiKey) { + headerParameters["x-api-key"] = this.configuration.apiKey("x-api-key"); // api_key authentication + } + + if (this.configuration && this.configuration.accessToken) { + const token = this.configuration.accessToken; + const tokenString = await token("bearer", []); + + if (tokenString) { + headerParameters["Authorization"] = `Bearer ${tokenString}`; + } + } + const response = await this.request({ + path: `/shared-link/me`, + method: 'GET', + headers: headerParameters, + query: queryParameters, + }, initOverrides); + + return new runtime.JSONApiResponse(response, (jsonValue) => SharedLinkResponseDtoFromJSON(jsonValue)); + } + + /** + */ + async getMySharedLink(requestParameters: GetMySharedLinkRequest = {}, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise { + const response = await this.getMySharedLinkRaw(requestParameters, initOverrides); + return await response.value(); + } + + /** + */ + async getSharedLinkByIdRaw(requestParameters: GetSharedLinkByIdRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise> { + if (requestParameters.id === null || requestParameters.id === undefined) { + throw new runtime.RequiredError('id','Required parameter requestParameters.id was null or undefined when calling getSharedLinkById.'); + } + + const queryParameters: any = {}; + + const headerParameters: runtime.HTTPHeaders = {}; + + if (this.configuration && this.configuration.apiKey) { + headerParameters["x-api-key"] = this.configuration.apiKey("x-api-key"); // api_key authentication + } + + if (this.configuration && this.configuration.accessToken) { + const token = this.configuration.accessToken; + const tokenString = await token("bearer", []); + + if (tokenString) { + headerParameters["Authorization"] = `Bearer ${tokenString}`; + } + } + const response = await this.request({ + path: `/shared-link/{id}`.replace(`{${"id"}}`, encodeURIComponent(String(requestParameters.id))), + method: 'GET', + headers: headerParameters, + query: queryParameters, + }, initOverrides); + + return new runtime.JSONApiResponse(response, (jsonValue) => SharedLinkResponseDtoFromJSON(jsonValue)); + } + + /** + */ + async getSharedLinkById(requestParameters: GetSharedLinkByIdRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise { + const response = await this.getSharedLinkByIdRaw(requestParameters, initOverrides); + return await response.value(); + } + + /** + */ + async removeSharedLinkRaw(requestParameters: RemoveSharedLinkRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise> { + if (requestParameters.id === null || requestParameters.id === undefined) { + throw new runtime.RequiredError('id','Required parameter requestParameters.id was null or undefined when calling removeSharedLink.'); + } + + const queryParameters: any = {}; + + const headerParameters: runtime.HTTPHeaders = {}; + + if (this.configuration && this.configuration.apiKey) { + headerParameters["x-api-key"] = this.configuration.apiKey("x-api-key"); // api_key authentication + } + + if (this.configuration && this.configuration.accessToken) { + const token = this.configuration.accessToken; + const tokenString = await token("bearer", []); + + if (tokenString) { + headerParameters["Authorization"] = `Bearer ${tokenString}`; + } + } + const response = await this.request({ + path: `/shared-link/{id}`.replace(`{${"id"}}`, encodeURIComponent(String(requestParameters.id))), + method: 'DELETE', + headers: headerParameters, + query: queryParameters, + }, initOverrides); + + return new runtime.VoidApiResponse(response); + } + + /** + */ + async removeSharedLink(requestParameters: RemoveSharedLinkRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise { + await this.removeSharedLinkRaw(requestParameters, initOverrides); + } + + /** + */ + async removeSharedLinkAssetsRaw(requestParameters: RemoveSharedLinkAssetsRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise>> { + if (requestParameters.id === null || requestParameters.id === undefined) { + throw new runtime.RequiredError('id','Required parameter requestParameters.id was null or undefined when calling removeSharedLinkAssets.'); + } + + if (requestParameters.assetIdsDto === null || requestParameters.assetIdsDto === undefined) { + throw new runtime.RequiredError('assetIdsDto','Required parameter requestParameters.assetIdsDto was null or undefined when calling removeSharedLinkAssets.'); + } + + const queryParameters: any = {}; + + if (requestParameters.key !== undefined) { + queryParameters['key'] = requestParameters.key; + } + + const headerParameters: runtime.HTTPHeaders = {}; + + headerParameters['Content-Type'] = 'application/json'; + + if (this.configuration && this.configuration.apiKey) { + headerParameters["x-api-key"] = this.configuration.apiKey("x-api-key"); // api_key authentication + } + + if (this.configuration && this.configuration.accessToken) { + const token = this.configuration.accessToken; + const tokenString = await token("bearer", []); + + if (tokenString) { + headerParameters["Authorization"] = `Bearer ${tokenString}`; + } + } + const response = await this.request({ + path: `/shared-link/{id}/assets`.replace(`{${"id"}}`, encodeURIComponent(String(requestParameters.id))), + method: 'DELETE', + headers: headerParameters, + query: queryParameters, + body: AssetIdsDtoToJSON(requestParameters.assetIdsDto), + }, initOverrides); + + return new runtime.JSONApiResponse(response, (jsonValue) => jsonValue.map(AssetIdsResponseDtoFromJSON)); + } + + /** + */ + async removeSharedLinkAssets(requestParameters: RemoveSharedLinkAssetsRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise> { + const response = await this.removeSharedLinkAssetsRaw(requestParameters, initOverrides); + return await response.value(); + } + + /** + */ + async updateSharedLinkRaw(requestParameters: UpdateSharedLinkRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise> { + if (requestParameters.id === null || requestParameters.id === undefined) { + throw new runtime.RequiredError('id','Required parameter requestParameters.id was null or undefined when calling updateSharedLink.'); + } + + if (requestParameters.sharedLinkEditDto === null || requestParameters.sharedLinkEditDto === undefined) { + throw new runtime.RequiredError('sharedLinkEditDto','Required parameter requestParameters.sharedLinkEditDto was null or undefined when calling updateSharedLink.'); + } + + const queryParameters: any = {}; + + const headerParameters: runtime.HTTPHeaders = {}; + + headerParameters['Content-Type'] = 'application/json'; + + if (this.configuration && this.configuration.apiKey) { + headerParameters["x-api-key"] = this.configuration.apiKey("x-api-key"); // api_key authentication + } + + if (this.configuration && this.configuration.accessToken) { + const token = this.configuration.accessToken; + const tokenString = await token("bearer", []); + + if (tokenString) { + headerParameters["Authorization"] = `Bearer ${tokenString}`; + } + } + const response = await this.request({ + path: `/shared-link/{id}`.replace(`{${"id"}}`, encodeURIComponent(String(requestParameters.id))), + method: 'PATCH', + headers: headerParameters, + query: queryParameters, + body: SharedLinkEditDtoToJSON(requestParameters.sharedLinkEditDto), + }, initOverrides); + + return new runtime.JSONApiResponse(response, (jsonValue) => SharedLinkResponseDtoFromJSON(jsonValue)); + } + + /** + */ + async updateSharedLink(requestParameters: UpdateSharedLinkRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise { + const response = await this.updateSharedLinkRaw(requestParameters, initOverrides); + return await response.value(); + } + +} diff --git a/open-api/typescript-sdk/fetch-client/apis/SystemConfigApi.ts b/open-api/typescript-sdk/fetch-client/apis/SystemConfigApi.ts new file mode 100644 index 0000000000..adafb3de95 --- /dev/null +++ b/open-api/typescript-sdk/fetch-client/apis/SystemConfigApi.ts @@ -0,0 +1,239 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * Immich + * Immich API + * + * The version of the OpenAPI document: 1.94.1 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + + +import * as runtime from '../runtime'; +import type { + MapTheme, + SystemConfigDto, + SystemConfigTemplateStorageOptionDto, +} from '../models/index'; +import { + MapThemeFromJSON, + MapThemeToJSON, + SystemConfigDtoFromJSON, + SystemConfigDtoToJSON, + SystemConfigTemplateStorageOptionDtoFromJSON, + SystemConfigTemplateStorageOptionDtoToJSON, +} from '../models/index'; + +export interface GetMapStyleRequest { + theme: MapTheme; +} + +export interface UpdateConfigRequest { + systemConfigDto: SystemConfigDto; +} + +/** + * + */ +export class SystemConfigApi extends runtime.BaseAPI { + + /** + */ + async getConfigRaw(initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise> { + const queryParameters: any = {}; + + const headerParameters: runtime.HTTPHeaders = {}; + + if (this.configuration && this.configuration.apiKey) { + headerParameters["x-api-key"] = this.configuration.apiKey("x-api-key"); // api_key authentication + } + + if (this.configuration && this.configuration.accessToken) { + const token = this.configuration.accessToken; + const tokenString = await token("bearer", []); + + if (tokenString) { + headerParameters["Authorization"] = `Bearer ${tokenString}`; + } + } + const response = await this.request({ + path: `/system-config`, + method: 'GET', + headers: headerParameters, + query: queryParameters, + }, initOverrides); + + return new runtime.JSONApiResponse(response, (jsonValue) => SystemConfigDtoFromJSON(jsonValue)); + } + + /** + */ + async getConfig(initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise { + const response = await this.getConfigRaw(initOverrides); + return await response.value(); + } + + /** + */ + async getConfigDefaultsRaw(initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise> { + const queryParameters: any = {}; + + const headerParameters: runtime.HTTPHeaders = {}; + + if (this.configuration && this.configuration.apiKey) { + headerParameters["x-api-key"] = this.configuration.apiKey("x-api-key"); // api_key authentication + } + + if (this.configuration && this.configuration.accessToken) { + const token = this.configuration.accessToken; + const tokenString = await token("bearer", []); + + if (tokenString) { + headerParameters["Authorization"] = `Bearer ${tokenString}`; + } + } + const response = await this.request({ + path: `/system-config/defaults`, + method: 'GET', + headers: headerParameters, + query: queryParameters, + }, initOverrides); + + return new runtime.JSONApiResponse(response, (jsonValue) => SystemConfigDtoFromJSON(jsonValue)); + } + + /** + */ + async getConfigDefaults(initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise { + const response = await this.getConfigDefaultsRaw(initOverrides); + return await response.value(); + } + + /** + */ + async getMapStyleRaw(requestParameters: GetMapStyleRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise> { + if (requestParameters.theme === null || requestParameters.theme === undefined) { + throw new runtime.RequiredError('theme','Required parameter requestParameters.theme was null or undefined when calling getMapStyle.'); + } + + const queryParameters: any = {}; + + if (requestParameters.theme !== undefined) { + queryParameters['theme'] = requestParameters.theme; + } + + const headerParameters: runtime.HTTPHeaders = {}; + + if (this.configuration && this.configuration.apiKey) { + headerParameters["x-api-key"] = this.configuration.apiKey("x-api-key"); // api_key authentication + } + + if (this.configuration && this.configuration.accessToken) { + const token = this.configuration.accessToken; + const tokenString = await token("bearer", []); + + if (tokenString) { + headerParameters["Authorization"] = `Bearer ${tokenString}`; + } + } + const response = await this.request({ + path: `/system-config/map/style.json`, + method: 'GET', + headers: headerParameters, + query: queryParameters, + }, initOverrides); + + return new runtime.JSONApiResponse(response); + } + + /** + */ + async getMapStyle(requestParameters: GetMapStyleRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise { + const response = await this.getMapStyleRaw(requestParameters, initOverrides); + return await response.value(); + } + + /** + */ + async getStorageTemplateOptionsRaw(initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise> { + const queryParameters: any = {}; + + const headerParameters: runtime.HTTPHeaders = {}; + + if (this.configuration && this.configuration.apiKey) { + headerParameters["x-api-key"] = this.configuration.apiKey("x-api-key"); // api_key authentication + } + + if (this.configuration && this.configuration.accessToken) { + const token = this.configuration.accessToken; + const tokenString = await token("bearer", []); + + if (tokenString) { + headerParameters["Authorization"] = `Bearer ${tokenString}`; + } + } + const response = await this.request({ + path: `/system-config/storage-template-options`, + method: 'GET', + headers: headerParameters, + query: queryParameters, + }, initOverrides); + + return new runtime.JSONApiResponse(response, (jsonValue) => SystemConfigTemplateStorageOptionDtoFromJSON(jsonValue)); + } + + /** + */ + async getStorageTemplateOptions(initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise { + const response = await this.getStorageTemplateOptionsRaw(initOverrides); + return await response.value(); + } + + /** + */ + async updateConfigRaw(requestParameters: UpdateConfigRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise> { + if (requestParameters.systemConfigDto === null || requestParameters.systemConfigDto === undefined) { + throw new runtime.RequiredError('systemConfigDto','Required parameter requestParameters.systemConfigDto was null or undefined when calling updateConfig.'); + } + + const queryParameters: any = {}; + + const headerParameters: runtime.HTTPHeaders = {}; + + headerParameters['Content-Type'] = 'application/json'; + + if (this.configuration && this.configuration.apiKey) { + headerParameters["x-api-key"] = this.configuration.apiKey("x-api-key"); // api_key authentication + } + + if (this.configuration && this.configuration.accessToken) { + const token = this.configuration.accessToken; + const tokenString = await token("bearer", []); + + if (tokenString) { + headerParameters["Authorization"] = `Bearer ${tokenString}`; + } + } + const response = await this.request({ + path: `/system-config`, + method: 'PUT', + headers: headerParameters, + query: queryParameters, + body: SystemConfigDtoToJSON(requestParameters.systemConfigDto), + }, initOverrides); + + return new runtime.JSONApiResponse(response, (jsonValue) => SystemConfigDtoFromJSON(jsonValue)); + } + + /** + */ + async updateConfig(requestParameters: UpdateConfigRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise { + const response = await this.updateConfigRaw(requestParameters, initOverrides); + return await response.value(); + } + +} diff --git a/open-api/typescript-sdk/fetch-client/apis/TagApi.ts b/open-api/typescript-sdk/fetch-client/apis/TagApi.ts new file mode 100644 index 0000000000..9fdeecd7e7 --- /dev/null +++ b/open-api/typescript-sdk/fetch-client/apis/TagApi.ts @@ -0,0 +1,415 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * Immich + * Immich API + * + * The version of the OpenAPI document: 1.94.1 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + + +import * as runtime from '../runtime'; +import type { + AssetIdsDto, + AssetIdsResponseDto, + AssetResponseDto, + CreateTagDto, + TagResponseDto, + UpdateTagDto, +} from '../models/index'; +import { + AssetIdsDtoFromJSON, + AssetIdsDtoToJSON, + AssetIdsResponseDtoFromJSON, + AssetIdsResponseDtoToJSON, + AssetResponseDtoFromJSON, + AssetResponseDtoToJSON, + CreateTagDtoFromJSON, + CreateTagDtoToJSON, + TagResponseDtoFromJSON, + TagResponseDtoToJSON, + UpdateTagDtoFromJSON, + UpdateTagDtoToJSON, +} from '../models/index'; + +export interface CreateTagRequest { + createTagDto: CreateTagDto; +} + +export interface DeleteTagRequest { + id: string; +} + +export interface GetTagAssetsRequest { + id: string; +} + +export interface GetTagByIdRequest { + id: string; +} + +export interface TagAssetsRequest { + id: string; + assetIdsDto: AssetIdsDto; +} + +export interface UntagAssetsRequest { + id: string; + assetIdsDto: AssetIdsDto; +} + +export interface UpdateTagRequest { + id: string; + updateTagDto: UpdateTagDto; +} + +/** + * + */ +export class TagApi extends runtime.BaseAPI { + + /** + */ + async createTagRaw(requestParameters: CreateTagRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise> { + if (requestParameters.createTagDto === null || requestParameters.createTagDto === undefined) { + throw new runtime.RequiredError('createTagDto','Required parameter requestParameters.createTagDto was null or undefined when calling createTag.'); + } + + const queryParameters: any = {}; + + const headerParameters: runtime.HTTPHeaders = {}; + + headerParameters['Content-Type'] = 'application/json'; + + if (this.configuration && this.configuration.apiKey) { + headerParameters["x-api-key"] = this.configuration.apiKey("x-api-key"); // api_key authentication + } + + if (this.configuration && this.configuration.accessToken) { + const token = this.configuration.accessToken; + const tokenString = await token("bearer", []); + + if (tokenString) { + headerParameters["Authorization"] = `Bearer ${tokenString}`; + } + } + const response = await this.request({ + path: `/tag`, + method: 'POST', + headers: headerParameters, + query: queryParameters, + body: CreateTagDtoToJSON(requestParameters.createTagDto), + }, initOverrides); + + return new runtime.JSONApiResponse(response, (jsonValue) => TagResponseDtoFromJSON(jsonValue)); + } + + /** + */ + async createTag(requestParameters: CreateTagRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise { + const response = await this.createTagRaw(requestParameters, initOverrides); + return await response.value(); + } + + /** + */ + async deleteTagRaw(requestParameters: DeleteTagRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise> { + if (requestParameters.id === null || requestParameters.id === undefined) { + throw new runtime.RequiredError('id','Required parameter requestParameters.id was null or undefined when calling deleteTag.'); + } + + const queryParameters: any = {}; + + const headerParameters: runtime.HTTPHeaders = {}; + + if (this.configuration && this.configuration.apiKey) { + headerParameters["x-api-key"] = this.configuration.apiKey("x-api-key"); // api_key authentication + } + + if (this.configuration && this.configuration.accessToken) { + const token = this.configuration.accessToken; + const tokenString = await token("bearer", []); + + if (tokenString) { + headerParameters["Authorization"] = `Bearer ${tokenString}`; + } + } + const response = await this.request({ + path: `/tag/{id}`.replace(`{${"id"}}`, encodeURIComponent(String(requestParameters.id))), + method: 'DELETE', + headers: headerParameters, + query: queryParameters, + }, initOverrides); + + return new runtime.VoidApiResponse(response); + } + + /** + */ + async deleteTag(requestParameters: DeleteTagRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise { + await this.deleteTagRaw(requestParameters, initOverrides); + } + + /** + */ + async getAllTagsRaw(initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise>> { + const queryParameters: any = {}; + + const headerParameters: runtime.HTTPHeaders = {}; + + if (this.configuration && this.configuration.apiKey) { + headerParameters["x-api-key"] = this.configuration.apiKey("x-api-key"); // api_key authentication + } + + if (this.configuration && this.configuration.accessToken) { + const token = this.configuration.accessToken; + const tokenString = await token("bearer", []); + + if (tokenString) { + headerParameters["Authorization"] = `Bearer ${tokenString}`; + } + } + const response = await this.request({ + path: `/tag`, + method: 'GET', + headers: headerParameters, + query: queryParameters, + }, initOverrides); + + return new runtime.JSONApiResponse(response, (jsonValue) => jsonValue.map(TagResponseDtoFromJSON)); + } + + /** + */ + async getAllTags(initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise> { + const response = await this.getAllTagsRaw(initOverrides); + return await response.value(); + } + + /** + */ + async getTagAssetsRaw(requestParameters: GetTagAssetsRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise>> { + if (requestParameters.id === null || requestParameters.id === undefined) { + throw new runtime.RequiredError('id','Required parameter requestParameters.id was null or undefined when calling getTagAssets.'); + } + + const queryParameters: any = {}; + + const headerParameters: runtime.HTTPHeaders = {}; + + if (this.configuration && this.configuration.apiKey) { + headerParameters["x-api-key"] = this.configuration.apiKey("x-api-key"); // api_key authentication + } + + if (this.configuration && this.configuration.accessToken) { + const token = this.configuration.accessToken; + const tokenString = await token("bearer", []); + + if (tokenString) { + headerParameters["Authorization"] = `Bearer ${tokenString}`; + } + } + const response = await this.request({ + path: `/tag/{id}/assets`.replace(`{${"id"}}`, encodeURIComponent(String(requestParameters.id))), + method: 'GET', + headers: headerParameters, + query: queryParameters, + }, initOverrides); + + return new runtime.JSONApiResponse(response, (jsonValue) => jsonValue.map(AssetResponseDtoFromJSON)); + } + + /** + */ + async getTagAssets(requestParameters: GetTagAssetsRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise> { + const response = await this.getTagAssetsRaw(requestParameters, initOverrides); + return await response.value(); + } + + /** + */ + async getTagByIdRaw(requestParameters: GetTagByIdRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise> { + if (requestParameters.id === null || requestParameters.id === undefined) { + throw new runtime.RequiredError('id','Required parameter requestParameters.id was null or undefined when calling getTagById.'); + } + + const queryParameters: any = {}; + + const headerParameters: runtime.HTTPHeaders = {}; + + if (this.configuration && this.configuration.apiKey) { + headerParameters["x-api-key"] = this.configuration.apiKey("x-api-key"); // api_key authentication + } + + if (this.configuration && this.configuration.accessToken) { + const token = this.configuration.accessToken; + const tokenString = await token("bearer", []); + + if (tokenString) { + headerParameters["Authorization"] = `Bearer ${tokenString}`; + } + } + const response = await this.request({ + path: `/tag/{id}`.replace(`{${"id"}}`, encodeURIComponent(String(requestParameters.id))), + method: 'GET', + headers: headerParameters, + query: queryParameters, + }, initOverrides); + + return new runtime.JSONApiResponse(response, (jsonValue) => TagResponseDtoFromJSON(jsonValue)); + } + + /** + */ + async getTagById(requestParameters: GetTagByIdRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise { + const response = await this.getTagByIdRaw(requestParameters, initOverrides); + return await response.value(); + } + + /** + */ + async tagAssetsRaw(requestParameters: TagAssetsRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise>> { + if (requestParameters.id === null || requestParameters.id === undefined) { + throw new runtime.RequiredError('id','Required parameter requestParameters.id was null or undefined when calling tagAssets.'); + } + + if (requestParameters.assetIdsDto === null || requestParameters.assetIdsDto === undefined) { + throw new runtime.RequiredError('assetIdsDto','Required parameter requestParameters.assetIdsDto was null or undefined when calling tagAssets.'); + } + + const queryParameters: any = {}; + + const headerParameters: runtime.HTTPHeaders = {}; + + headerParameters['Content-Type'] = 'application/json'; + + if (this.configuration && this.configuration.apiKey) { + headerParameters["x-api-key"] = this.configuration.apiKey("x-api-key"); // api_key authentication + } + + if (this.configuration && this.configuration.accessToken) { + const token = this.configuration.accessToken; + const tokenString = await token("bearer", []); + + if (tokenString) { + headerParameters["Authorization"] = `Bearer ${tokenString}`; + } + } + const response = await this.request({ + path: `/tag/{id}/assets`.replace(`{${"id"}}`, encodeURIComponent(String(requestParameters.id))), + method: 'PUT', + headers: headerParameters, + query: queryParameters, + body: AssetIdsDtoToJSON(requestParameters.assetIdsDto), + }, initOverrides); + + return new runtime.JSONApiResponse(response, (jsonValue) => jsonValue.map(AssetIdsResponseDtoFromJSON)); + } + + /** + */ + async tagAssets(requestParameters: TagAssetsRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise> { + const response = await this.tagAssetsRaw(requestParameters, initOverrides); + return await response.value(); + } + + /** + */ + async untagAssetsRaw(requestParameters: UntagAssetsRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise>> { + if (requestParameters.id === null || requestParameters.id === undefined) { + throw new runtime.RequiredError('id','Required parameter requestParameters.id was null or undefined when calling untagAssets.'); + } + + if (requestParameters.assetIdsDto === null || requestParameters.assetIdsDto === undefined) { + throw new runtime.RequiredError('assetIdsDto','Required parameter requestParameters.assetIdsDto was null or undefined when calling untagAssets.'); + } + + const queryParameters: any = {}; + + const headerParameters: runtime.HTTPHeaders = {}; + + headerParameters['Content-Type'] = 'application/json'; + + if (this.configuration && this.configuration.apiKey) { + headerParameters["x-api-key"] = this.configuration.apiKey("x-api-key"); // api_key authentication + } + + if (this.configuration && this.configuration.accessToken) { + const token = this.configuration.accessToken; + const tokenString = await token("bearer", []); + + if (tokenString) { + headerParameters["Authorization"] = `Bearer ${tokenString}`; + } + } + const response = await this.request({ + path: `/tag/{id}/assets`.replace(`{${"id"}}`, encodeURIComponent(String(requestParameters.id))), + method: 'DELETE', + headers: headerParameters, + query: queryParameters, + body: AssetIdsDtoToJSON(requestParameters.assetIdsDto), + }, initOverrides); + + return new runtime.JSONApiResponse(response, (jsonValue) => jsonValue.map(AssetIdsResponseDtoFromJSON)); + } + + /** + */ + async untagAssets(requestParameters: UntagAssetsRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise> { + const response = await this.untagAssetsRaw(requestParameters, initOverrides); + return await response.value(); + } + + /** + */ + async updateTagRaw(requestParameters: UpdateTagRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise> { + if (requestParameters.id === null || requestParameters.id === undefined) { + throw new runtime.RequiredError('id','Required parameter requestParameters.id was null or undefined when calling updateTag.'); + } + + if (requestParameters.updateTagDto === null || requestParameters.updateTagDto === undefined) { + throw new runtime.RequiredError('updateTagDto','Required parameter requestParameters.updateTagDto was null or undefined when calling updateTag.'); + } + + const queryParameters: any = {}; + + const headerParameters: runtime.HTTPHeaders = {}; + + headerParameters['Content-Type'] = 'application/json'; + + if (this.configuration && this.configuration.apiKey) { + headerParameters["x-api-key"] = this.configuration.apiKey("x-api-key"); // api_key authentication + } + + if (this.configuration && this.configuration.accessToken) { + const token = this.configuration.accessToken; + const tokenString = await token("bearer", []); + + if (tokenString) { + headerParameters["Authorization"] = `Bearer ${tokenString}`; + } + } + const response = await this.request({ + path: `/tag/{id}`.replace(`{${"id"}}`, encodeURIComponent(String(requestParameters.id))), + method: 'PATCH', + headers: headerParameters, + query: queryParameters, + body: UpdateTagDtoToJSON(requestParameters.updateTagDto), + }, initOverrides); + + return new runtime.JSONApiResponse(response, (jsonValue) => TagResponseDtoFromJSON(jsonValue)); + } + + /** + */ + async updateTag(requestParameters: UpdateTagRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise { + const response = await this.updateTagRaw(requestParameters, initOverrides); + return await response.value(); + } + +} diff --git a/open-api/typescript-sdk/fetch-client/apis/TrashApi.ts b/open-api/typescript-sdk/fetch-client/apis/TrashApi.ts new file mode 100644 index 0000000000..d0f068be49 --- /dev/null +++ b/open-api/typescript-sdk/fetch-client/apis/TrashApi.ts @@ -0,0 +1,146 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * Immich + * Immich API + * + * The version of the OpenAPI document: 1.94.1 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + + +import * as runtime from '../runtime'; +import type { + BulkIdsDto, +} from '../models/index'; +import { + BulkIdsDtoFromJSON, + BulkIdsDtoToJSON, +} from '../models/index'; + +export interface RestoreAssetsRequest { + bulkIdsDto: BulkIdsDto; +} + +/** + * + */ +export class TrashApi extends runtime.BaseAPI { + + /** + */ + async emptyTrashRaw(initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise> { + const queryParameters: any = {}; + + const headerParameters: runtime.HTTPHeaders = {}; + + if (this.configuration && this.configuration.apiKey) { + headerParameters["x-api-key"] = this.configuration.apiKey("x-api-key"); // api_key authentication + } + + if (this.configuration && this.configuration.accessToken) { + const token = this.configuration.accessToken; + const tokenString = await token("bearer", []); + + if (tokenString) { + headerParameters["Authorization"] = `Bearer ${tokenString}`; + } + } + const response = await this.request({ + path: `/trash/empty`, + method: 'POST', + headers: headerParameters, + query: queryParameters, + }, initOverrides); + + return new runtime.VoidApiResponse(response); + } + + /** + */ + async emptyTrash(initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise { + await this.emptyTrashRaw(initOverrides); + } + + /** + */ + async restoreAssetsRaw(requestParameters: RestoreAssetsRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise> { + if (requestParameters.bulkIdsDto === null || requestParameters.bulkIdsDto === undefined) { + throw new runtime.RequiredError('bulkIdsDto','Required parameter requestParameters.bulkIdsDto was null or undefined when calling restoreAssets.'); + } + + const queryParameters: any = {}; + + const headerParameters: runtime.HTTPHeaders = {}; + + headerParameters['Content-Type'] = 'application/json'; + + if (this.configuration && this.configuration.apiKey) { + headerParameters["x-api-key"] = this.configuration.apiKey("x-api-key"); // api_key authentication + } + + if (this.configuration && this.configuration.accessToken) { + const token = this.configuration.accessToken; + const tokenString = await token("bearer", []); + + if (tokenString) { + headerParameters["Authorization"] = `Bearer ${tokenString}`; + } + } + const response = await this.request({ + path: `/trash/restore/assets`, + method: 'POST', + headers: headerParameters, + query: queryParameters, + body: BulkIdsDtoToJSON(requestParameters.bulkIdsDto), + }, initOverrides); + + return new runtime.VoidApiResponse(response); + } + + /** + */ + async restoreAssets(requestParameters: RestoreAssetsRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise { + await this.restoreAssetsRaw(requestParameters, initOverrides); + } + + /** + */ + async restoreTrashRaw(initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise> { + const queryParameters: any = {}; + + const headerParameters: runtime.HTTPHeaders = {}; + + if (this.configuration && this.configuration.apiKey) { + headerParameters["x-api-key"] = this.configuration.apiKey("x-api-key"); // api_key authentication + } + + if (this.configuration && this.configuration.accessToken) { + const token = this.configuration.accessToken; + const tokenString = await token("bearer", []); + + if (tokenString) { + headerParameters["Authorization"] = `Bearer ${tokenString}`; + } + } + const response = await this.request({ + path: `/trash/restore`, + method: 'POST', + headers: headerParameters, + query: queryParameters, + }, initOverrides); + + return new runtime.VoidApiResponse(response); + } + + /** + */ + async restoreTrash(initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise { + await this.restoreTrashRaw(initOverrides); + } + +} diff --git a/open-api/typescript-sdk/fetch-client/apis/UserApi.ts b/open-api/typescript-sdk/fetch-client/apis/UserApi.ts new file mode 100644 index 0000000000..d2af7f3edd --- /dev/null +++ b/open-api/typescript-sdk/fetch-client/apis/UserApi.ts @@ -0,0 +1,493 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * Immich + * Immich API + * + * The version of the OpenAPI document: 1.94.1 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + + +import * as runtime from '../runtime'; +import type { + CreateProfileImageResponseDto, + CreateUserDto, + UpdateUserDto, + UserResponseDto, +} from '../models/index'; +import { + CreateProfileImageResponseDtoFromJSON, + CreateProfileImageResponseDtoToJSON, + CreateUserDtoFromJSON, + CreateUserDtoToJSON, + UpdateUserDtoFromJSON, + UpdateUserDtoToJSON, + UserResponseDtoFromJSON, + UserResponseDtoToJSON, +} from '../models/index'; + +export interface CreateProfileImageRequest { + file: Blob; +} + +export interface CreateUserRequest { + createUserDto: CreateUserDto; +} + +export interface DeleteUserRequest { + id: string; +} + +export interface GetAllUsersRequest { + isAll: boolean; +} + +export interface GetProfileImageRequest { + id: string; +} + +export interface GetUserByIdRequest { + id: string; +} + +export interface RestoreUserRequest { + id: string; +} + +export interface UpdateUserRequest { + updateUserDto: UpdateUserDto; +} + +/** + * + */ +export class UserApi extends runtime.BaseAPI { + + /** + */ + async createProfileImageRaw(requestParameters: CreateProfileImageRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise> { + if (requestParameters.file === null || requestParameters.file === undefined) { + throw new runtime.RequiredError('file','Required parameter requestParameters.file was null or undefined when calling createProfileImage.'); + } + + const queryParameters: any = {}; + + const headerParameters: runtime.HTTPHeaders = {}; + + if (this.configuration && this.configuration.apiKey) { + headerParameters["x-api-key"] = this.configuration.apiKey("x-api-key"); // api_key authentication + } + + if (this.configuration && this.configuration.accessToken) { + const token = this.configuration.accessToken; + const tokenString = await token("bearer", []); + + if (tokenString) { + headerParameters["Authorization"] = `Bearer ${tokenString}`; + } + } + const consumes: runtime.Consume[] = [ + { contentType: 'multipart/form-data' }, + ]; + // @ts-ignore: canConsumeForm may be unused + const canConsumeForm = runtime.canConsumeForm(consumes); + + let formParams: { append(param: string, value: any): any }; + let useForm = false; + // use FormData to transmit files using content-type "multipart/form-data" + useForm = canConsumeForm; + if (useForm) { + formParams = new FormData(); + } else { + formParams = new URLSearchParams(); + } + + if (requestParameters.file !== undefined) { + formParams.append('file', requestParameters.file as any); + } + + const response = await this.request({ + path: `/user/profile-image`, + method: 'POST', + headers: headerParameters, + query: queryParameters, + body: formParams, + }, initOverrides); + + return new runtime.JSONApiResponse(response, (jsonValue) => CreateProfileImageResponseDtoFromJSON(jsonValue)); + } + + /** + */ + async createProfileImage(requestParameters: CreateProfileImageRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise { + const response = await this.createProfileImageRaw(requestParameters, initOverrides); + return await response.value(); + } + + /** + */ + async createUserRaw(requestParameters: CreateUserRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise> { + if (requestParameters.createUserDto === null || requestParameters.createUserDto === undefined) { + throw new runtime.RequiredError('createUserDto','Required parameter requestParameters.createUserDto was null or undefined when calling createUser.'); + } + + const queryParameters: any = {}; + + const headerParameters: runtime.HTTPHeaders = {}; + + headerParameters['Content-Type'] = 'application/json'; + + if (this.configuration && this.configuration.apiKey) { + headerParameters["x-api-key"] = this.configuration.apiKey("x-api-key"); // api_key authentication + } + + if (this.configuration && this.configuration.accessToken) { + const token = this.configuration.accessToken; + const tokenString = await token("bearer", []); + + if (tokenString) { + headerParameters["Authorization"] = `Bearer ${tokenString}`; + } + } + const response = await this.request({ + path: `/user`, + method: 'POST', + headers: headerParameters, + query: queryParameters, + body: CreateUserDtoToJSON(requestParameters.createUserDto), + }, initOverrides); + + return new runtime.JSONApiResponse(response, (jsonValue) => UserResponseDtoFromJSON(jsonValue)); + } + + /** + */ + async createUser(requestParameters: CreateUserRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise { + const response = await this.createUserRaw(requestParameters, initOverrides); + return await response.value(); + } + + /** + */ + async deleteProfileImageRaw(initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise> { + const queryParameters: any = {}; + + const headerParameters: runtime.HTTPHeaders = {}; + + if (this.configuration && this.configuration.apiKey) { + headerParameters["x-api-key"] = this.configuration.apiKey("x-api-key"); // api_key authentication + } + + if (this.configuration && this.configuration.accessToken) { + const token = this.configuration.accessToken; + const tokenString = await token("bearer", []); + + if (tokenString) { + headerParameters["Authorization"] = `Bearer ${tokenString}`; + } + } + const response = await this.request({ + path: `/user/profile-image`, + method: 'DELETE', + headers: headerParameters, + query: queryParameters, + }, initOverrides); + + return new runtime.VoidApiResponse(response); + } + + /** + */ + async deleteProfileImage(initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise { + await this.deleteProfileImageRaw(initOverrides); + } + + /** + */ + async deleteUserRaw(requestParameters: DeleteUserRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise> { + if (requestParameters.id === null || requestParameters.id === undefined) { + throw new runtime.RequiredError('id','Required parameter requestParameters.id was null or undefined when calling deleteUser.'); + } + + const queryParameters: any = {}; + + const headerParameters: runtime.HTTPHeaders = {}; + + if (this.configuration && this.configuration.apiKey) { + headerParameters["x-api-key"] = this.configuration.apiKey("x-api-key"); // api_key authentication + } + + if (this.configuration && this.configuration.accessToken) { + const token = this.configuration.accessToken; + const tokenString = await token("bearer", []); + + if (tokenString) { + headerParameters["Authorization"] = `Bearer ${tokenString}`; + } + } + const response = await this.request({ + path: `/user/{id}`.replace(`{${"id"}}`, encodeURIComponent(String(requestParameters.id))), + method: 'DELETE', + headers: headerParameters, + query: queryParameters, + }, initOverrides); + + return new runtime.JSONApiResponse(response, (jsonValue) => UserResponseDtoFromJSON(jsonValue)); + } + + /** + */ + async deleteUser(requestParameters: DeleteUserRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise { + const response = await this.deleteUserRaw(requestParameters, initOverrides); + return await response.value(); + } + + /** + */ + async getAllUsersRaw(requestParameters: GetAllUsersRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise>> { + if (requestParameters.isAll === null || requestParameters.isAll === undefined) { + throw new runtime.RequiredError('isAll','Required parameter requestParameters.isAll was null or undefined when calling getAllUsers.'); + } + + const queryParameters: any = {}; + + if (requestParameters.isAll !== undefined) { + queryParameters['isAll'] = requestParameters.isAll; + } + + const headerParameters: runtime.HTTPHeaders = {}; + + if (this.configuration && this.configuration.apiKey) { + headerParameters["x-api-key"] = this.configuration.apiKey("x-api-key"); // api_key authentication + } + + if (this.configuration && this.configuration.accessToken) { + const token = this.configuration.accessToken; + const tokenString = await token("bearer", []); + + if (tokenString) { + headerParameters["Authorization"] = `Bearer ${tokenString}`; + } + } + const response = await this.request({ + path: `/user`, + method: 'GET', + headers: headerParameters, + query: queryParameters, + }, initOverrides); + + return new runtime.JSONApiResponse(response, (jsonValue) => jsonValue.map(UserResponseDtoFromJSON)); + } + + /** + */ + async getAllUsers(requestParameters: GetAllUsersRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise> { + const response = await this.getAllUsersRaw(requestParameters, initOverrides); + return await response.value(); + } + + /** + */ + async getMyUserInfoRaw(initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise> { + const queryParameters: any = {}; + + const headerParameters: runtime.HTTPHeaders = {}; + + if (this.configuration && this.configuration.apiKey) { + headerParameters["x-api-key"] = this.configuration.apiKey("x-api-key"); // api_key authentication + } + + if (this.configuration && this.configuration.accessToken) { + const token = this.configuration.accessToken; + const tokenString = await token("bearer", []); + + if (tokenString) { + headerParameters["Authorization"] = `Bearer ${tokenString}`; + } + } + const response = await this.request({ + path: `/user/me`, + method: 'GET', + headers: headerParameters, + query: queryParameters, + }, initOverrides); + + return new runtime.JSONApiResponse(response, (jsonValue) => UserResponseDtoFromJSON(jsonValue)); + } + + /** + */ + async getMyUserInfo(initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise { + const response = await this.getMyUserInfoRaw(initOverrides); + return await response.value(); + } + + /** + */ + async getProfileImageRaw(requestParameters: GetProfileImageRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise> { + if (requestParameters.id === null || requestParameters.id === undefined) { + throw new runtime.RequiredError('id','Required parameter requestParameters.id was null or undefined when calling getProfileImage.'); + } + + const queryParameters: any = {}; + + const headerParameters: runtime.HTTPHeaders = {}; + + if (this.configuration && this.configuration.apiKey) { + headerParameters["x-api-key"] = this.configuration.apiKey("x-api-key"); // api_key authentication + } + + if (this.configuration && this.configuration.accessToken) { + const token = this.configuration.accessToken; + const tokenString = await token("bearer", []); + + if (tokenString) { + headerParameters["Authorization"] = `Bearer ${tokenString}`; + } + } + const response = await this.request({ + path: `/user/profile-image/{id}`.replace(`{${"id"}}`, encodeURIComponent(String(requestParameters.id))), + method: 'GET', + headers: headerParameters, + query: queryParameters, + }, initOverrides); + + return new runtime.BlobApiResponse(response); + } + + /** + */ + async getProfileImage(requestParameters: GetProfileImageRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise { + const response = await this.getProfileImageRaw(requestParameters, initOverrides); + return await response.value(); + } + + /** + */ + async getUserByIdRaw(requestParameters: GetUserByIdRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise> { + if (requestParameters.id === null || requestParameters.id === undefined) { + throw new runtime.RequiredError('id','Required parameter requestParameters.id was null or undefined when calling getUserById.'); + } + + const queryParameters: any = {}; + + const headerParameters: runtime.HTTPHeaders = {}; + + if (this.configuration && this.configuration.apiKey) { + headerParameters["x-api-key"] = this.configuration.apiKey("x-api-key"); // api_key authentication + } + + if (this.configuration && this.configuration.accessToken) { + const token = this.configuration.accessToken; + const tokenString = await token("bearer", []); + + if (tokenString) { + headerParameters["Authorization"] = `Bearer ${tokenString}`; + } + } + const response = await this.request({ + path: `/user/info/{id}`.replace(`{${"id"}}`, encodeURIComponent(String(requestParameters.id))), + method: 'GET', + headers: headerParameters, + query: queryParameters, + }, initOverrides); + + return new runtime.JSONApiResponse(response, (jsonValue) => UserResponseDtoFromJSON(jsonValue)); + } + + /** + */ + async getUserById(requestParameters: GetUserByIdRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise { + const response = await this.getUserByIdRaw(requestParameters, initOverrides); + return await response.value(); + } + + /** + */ + async restoreUserRaw(requestParameters: RestoreUserRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise> { + if (requestParameters.id === null || requestParameters.id === undefined) { + throw new runtime.RequiredError('id','Required parameter requestParameters.id was null or undefined when calling restoreUser.'); + } + + const queryParameters: any = {}; + + const headerParameters: runtime.HTTPHeaders = {}; + + if (this.configuration && this.configuration.apiKey) { + headerParameters["x-api-key"] = this.configuration.apiKey("x-api-key"); // api_key authentication + } + + if (this.configuration && this.configuration.accessToken) { + const token = this.configuration.accessToken; + const tokenString = await token("bearer", []); + + if (tokenString) { + headerParameters["Authorization"] = `Bearer ${tokenString}`; + } + } + const response = await this.request({ + path: `/user/{id}/restore`.replace(`{${"id"}}`, encodeURIComponent(String(requestParameters.id))), + method: 'POST', + headers: headerParameters, + query: queryParameters, + }, initOverrides); + + return new runtime.JSONApiResponse(response, (jsonValue) => UserResponseDtoFromJSON(jsonValue)); + } + + /** + */ + async restoreUser(requestParameters: RestoreUserRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise { + const response = await this.restoreUserRaw(requestParameters, initOverrides); + return await response.value(); + } + + /** + */ + async updateUserRaw(requestParameters: UpdateUserRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise> { + if (requestParameters.updateUserDto === null || requestParameters.updateUserDto === undefined) { + throw new runtime.RequiredError('updateUserDto','Required parameter requestParameters.updateUserDto was null or undefined when calling updateUser.'); + } + + const queryParameters: any = {}; + + const headerParameters: runtime.HTTPHeaders = {}; + + headerParameters['Content-Type'] = 'application/json'; + + if (this.configuration && this.configuration.apiKey) { + headerParameters["x-api-key"] = this.configuration.apiKey("x-api-key"); // api_key authentication + } + + if (this.configuration && this.configuration.accessToken) { + const token = this.configuration.accessToken; + const tokenString = await token("bearer", []); + + if (tokenString) { + headerParameters["Authorization"] = `Bearer ${tokenString}`; + } + } + const response = await this.request({ + path: `/user`, + method: 'PUT', + headers: headerParameters, + query: queryParameters, + body: UpdateUserDtoToJSON(requestParameters.updateUserDto), + }, initOverrides); + + return new runtime.JSONApiResponse(response, (jsonValue) => UserResponseDtoFromJSON(jsonValue)); + } + + /** + */ + async updateUser(requestParameters: UpdateUserRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise { + const response = await this.updateUserRaw(requestParameters, initOverrides); + return await response.value(); + } + +} diff --git a/open-api/typescript-sdk/fetch-client/apis/index.ts b/open-api/typescript-sdk/fetch-client/apis/index.ts new file mode 100644 index 0000000000..465777a562 --- /dev/null +++ b/open-api/typescript-sdk/fetch-client/apis/index.ts @@ -0,0 +1,22 @@ +/* tslint:disable */ +/* eslint-disable */ +export * from './APIKeyApi'; +export * from './ActivityApi'; +export * from './AlbumApi'; +export * from './AssetApi'; +export * from './AuditApi'; +export * from './AuthenticationApi'; +export * from './DownloadApi'; +export * from './FaceApi'; +export * from './JobApi'; +export * from './LibraryApi'; +export * from './OAuthApi'; +export * from './PartnerApi'; +export * from './PersonApi'; +export * from './SearchApi'; +export * from './ServerInfoApi'; +export * from './SharedLinkApi'; +export * from './SystemConfigApi'; +export * from './TagApi'; +export * from './TrashApi'; +export * from './UserApi'; diff --git a/open-api/typescript-sdk/fetch-client/index.ts b/open-api/typescript-sdk/fetch-client/index.ts new file mode 100644 index 0000000000..bebe8bbbe2 --- /dev/null +++ b/open-api/typescript-sdk/fetch-client/index.ts @@ -0,0 +1,5 @@ +/* tslint:disable */ +/* eslint-disable */ +export * from './runtime'; +export * from './apis/index'; +export * from './models/index'; diff --git a/open-api/typescript-sdk/fetch-client/models/APIKeyCreateDto.ts b/open-api/typescript-sdk/fetch-client/models/APIKeyCreateDto.ts new file mode 100644 index 0000000000..ed88f1d622 --- /dev/null +++ b/open-api/typescript-sdk/fetch-client/models/APIKeyCreateDto.ts @@ -0,0 +1,65 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * Immich + * Immich API + * + * The version of the OpenAPI document: 1.94.1 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + +import { exists, mapValues } from '../runtime'; +/** + * + * @export + * @interface APIKeyCreateDto + */ +export interface APIKeyCreateDto { + /** + * + * @type {string} + * @memberof APIKeyCreateDto + */ + name?: string; +} + +/** + * Check if a given object implements the APIKeyCreateDto interface. + */ +export function instanceOfAPIKeyCreateDto(value: object): boolean { + let isInstance = true; + + return isInstance; +} + +export function APIKeyCreateDtoFromJSON(json: any): APIKeyCreateDto { + return APIKeyCreateDtoFromJSONTyped(json, false); +} + +export function APIKeyCreateDtoFromJSONTyped(json: any, ignoreDiscriminator: boolean): APIKeyCreateDto { + if ((json === undefined) || (json === null)) { + return json; + } + return { + + 'name': !exists(json, 'name') ? undefined : json['name'], + }; +} + +export function APIKeyCreateDtoToJSON(value?: APIKeyCreateDto | null): any { + if (value === undefined) { + return undefined; + } + if (value === null) { + return null; + } + return { + + 'name': value.name, + }; +} + diff --git a/open-api/typescript-sdk/fetch-client/models/APIKeyCreateResponseDto.ts b/open-api/typescript-sdk/fetch-client/models/APIKeyCreateResponseDto.ts new file mode 100644 index 0000000000..d0c0bd3426 --- /dev/null +++ b/open-api/typescript-sdk/fetch-client/models/APIKeyCreateResponseDto.ts @@ -0,0 +1,82 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * Immich + * Immich API + * + * The version of the OpenAPI document: 1.94.1 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + +import { exists, mapValues } from '../runtime'; +import type { APIKeyResponseDto } from './APIKeyResponseDto'; +import { + APIKeyResponseDtoFromJSON, + APIKeyResponseDtoFromJSONTyped, + APIKeyResponseDtoToJSON, +} from './APIKeyResponseDto'; + +/** + * + * @export + * @interface APIKeyCreateResponseDto + */ +export interface APIKeyCreateResponseDto { + /** + * + * @type {APIKeyResponseDto} + * @memberof APIKeyCreateResponseDto + */ + apiKey: APIKeyResponseDto; + /** + * + * @type {string} + * @memberof APIKeyCreateResponseDto + */ + secret: string; +} + +/** + * Check if a given object implements the APIKeyCreateResponseDto interface. + */ +export function instanceOfAPIKeyCreateResponseDto(value: object): boolean { + let isInstance = true; + isInstance = isInstance && "apiKey" in value; + isInstance = isInstance && "secret" in value; + + return isInstance; +} + +export function APIKeyCreateResponseDtoFromJSON(json: any): APIKeyCreateResponseDto { + return APIKeyCreateResponseDtoFromJSONTyped(json, false); +} + +export function APIKeyCreateResponseDtoFromJSONTyped(json: any, ignoreDiscriminator: boolean): APIKeyCreateResponseDto { + if ((json === undefined) || (json === null)) { + return json; + } + return { + + 'apiKey': APIKeyResponseDtoFromJSON(json['apiKey']), + 'secret': json['secret'], + }; +} + +export function APIKeyCreateResponseDtoToJSON(value?: APIKeyCreateResponseDto | null): any { + if (value === undefined) { + return undefined; + } + if (value === null) { + return null; + } + return { + + 'apiKey': APIKeyResponseDtoToJSON(value.apiKey), + 'secret': value.secret, + }; +} + diff --git a/open-api/typescript-sdk/fetch-client/models/APIKeyResponseDto.ts b/open-api/typescript-sdk/fetch-client/models/APIKeyResponseDto.ts new file mode 100644 index 0000000000..72ed62793c --- /dev/null +++ b/open-api/typescript-sdk/fetch-client/models/APIKeyResponseDto.ts @@ -0,0 +1,93 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * Immich + * Immich API + * + * The version of the OpenAPI document: 1.94.1 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + +import { exists, mapValues } from '../runtime'; +/** + * + * @export + * @interface APIKeyResponseDto + */ +export interface APIKeyResponseDto { + /** + * + * @type {Date} + * @memberof APIKeyResponseDto + */ + createdAt: Date; + /** + * + * @type {string} + * @memberof APIKeyResponseDto + */ + id: string; + /** + * + * @type {string} + * @memberof APIKeyResponseDto + */ + name: string; + /** + * + * @type {Date} + * @memberof APIKeyResponseDto + */ + updatedAt: Date; +} + +/** + * Check if a given object implements the APIKeyResponseDto interface. + */ +export function instanceOfAPIKeyResponseDto(value: object): boolean { + let isInstance = true; + isInstance = isInstance && "createdAt" in value; + isInstance = isInstance && "id" in value; + isInstance = isInstance && "name" in value; + isInstance = isInstance && "updatedAt" in value; + + return isInstance; +} + +export function APIKeyResponseDtoFromJSON(json: any): APIKeyResponseDto { + return APIKeyResponseDtoFromJSONTyped(json, false); +} + +export function APIKeyResponseDtoFromJSONTyped(json: any, ignoreDiscriminator: boolean): APIKeyResponseDto { + if ((json === undefined) || (json === null)) { + return json; + } + return { + + 'createdAt': (new Date(json['createdAt'])), + 'id': json['id'], + 'name': json['name'], + 'updatedAt': (new Date(json['updatedAt'])), + }; +} + +export function APIKeyResponseDtoToJSON(value?: APIKeyResponseDto | null): any { + if (value === undefined) { + return undefined; + } + if (value === null) { + return null; + } + return { + + 'createdAt': (value.createdAt.toISOString()), + 'id': value.id, + 'name': value.name, + 'updatedAt': (value.updatedAt.toISOString()), + }; +} + diff --git a/open-api/typescript-sdk/fetch-client/models/APIKeyUpdateDto.ts b/open-api/typescript-sdk/fetch-client/models/APIKeyUpdateDto.ts new file mode 100644 index 0000000000..d32e13c865 --- /dev/null +++ b/open-api/typescript-sdk/fetch-client/models/APIKeyUpdateDto.ts @@ -0,0 +1,66 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * Immich + * Immich API + * + * The version of the OpenAPI document: 1.94.1 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + +import { exists, mapValues } from '../runtime'; +/** + * + * @export + * @interface APIKeyUpdateDto + */ +export interface APIKeyUpdateDto { + /** + * + * @type {string} + * @memberof APIKeyUpdateDto + */ + name: string; +} + +/** + * Check if a given object implements the APIKeyUpdateDto interface. + */ +export function instanceOfAPIKeyUpdateDto(value: object): boolean { + let isInstance = true; + isInstance = isInstance && "name" in value; + + return isInstance; +} + +export function APIKeyUpdateDtoFromJSON(json: any): APIKeyUpdateDto { + return APIKeyUpdateDtoFromJSONTyped(json, false); +} + +export function APIKeyUpdateDtoFromJSONTyped(json: any, ignoreDiscriminator: boolean): APIKeyUpdateDto { + if ((json === undefined) || (json === null)) { + return json; + } + return { + + 'name': json['name'], + }; +} + +export function APIKeyUpdateDtoToJSON(value?: APIKeyUpdateDto | null): any { + if (value === undefined) { + return undefined; + } + if (value === null) { + return null; + } + return { + + 'name': value.name, + }; +} + diff --git a/open-api/typescript-sdk/fetch-client/models/ActivityCreateDto.ts b/open-api/typescript-sdk/fetch-client/models/ActivityCreateDto.ts new file mode 100644 index 0000000000..7f27de3537 --- /dev/null +++ b/open-api/typescript-sdk/fetch-client/models/ActivityCreateDto.ts @@ -0,0 +1,98 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * Immich + * Immich API + * + * The version of the OpenAPI document: 1.94.1 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + +import { exists, mapValues } from '../runtime'; +import type { ReactionType } from './ReactionType'; +import { + ReactionTypeFromJSON, + ReactionTypeFromJSONTyped, + ReactionTypeToJSON, +} from './ReactionType'; + +/** + * + * @export + * @interface ActivityCreateDto + */ +export interface ActivityCreateDto { + /** + * + * @type {string} + * @memberof ActivityCreateDto + */ + albumId: string; + /** + * + * @type {string} + * @memberof ActivityCreateDto + */ + assetId?: string; + /** + * + * @type {string} + * @memberof ActivityCreateDto + */ + comment?: string; + /** + * + * @type {ReactionType} + * @memberof ActivityCreateDto + */ + type: ReactionType; +} + +/** + * Check if a given object implements the ActivityCreateDto interface. + */ +export function instanceOfActivityCreateDto(value: object): boolean { + let isInstance = true; + isInstance = isInstance && "albumId" in value; + isInstance = isInstance && "type" in value; + + return isInstance; +} + +export function ActivityCreateDtoFromJSON(json: any): ActivityCreateDto { + return ActivityCreateDtoFromJSONTyped(json, false); +} + +export function ActivityCreateDtoFromJSONTyped(json: any, ignoreDiscriminator: boolean): ActivityCreateDto { + if ((json === undefined) || (json === null)) { + return json; + } + return { + + 'albumId': json['albumId'], + 'assetId': !exists(json, 'assetId') ? undefined : json['assetId'], + 'comment': !exists(json, 'comment') ? undefined : json['comment'], + 'type': ReactionTypeFromJSON(json['type']), + }; +} + +export function ActivityCreateDtoToJSON(value?: ActivityCreateDto | null): any { + if (value === undefined) { + return undefined; + } + if (value === null) { + return null; + } + return { + + 'albumId': value.albumId, + 'assetId': value.assetId, + 'comment': value.comment, + 'type': ReactionTypeToJSON(value.type), + }; +} + diff --git a/open-api/typescript-sdk/fetch-client/models/ActivityResponseDto.ts b/open-api/typescript-sdk/fetch-client/models/ActivityResponseDto.ts new file mode 100644 index 0000000000..762bd62aa9 --- /dev/null +++ b/open-api/typescript-sdk/fetch-client/models/ActivityResponseDto.ts @@ -0,0 +1,128 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * Immich + * Immich API + * + * The version of the OpenAPI document: 1.94.1 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + +import { exists, mapValues } from '../runtime'; +import type { UserDto } from './UserDto'; +import { + UserDtoFromJSON, + UserDtoFromJSONTyped, + UserDtoToJSON, +} from './UserDto'; + +/** + * + * @export + * @interface ActivityResponseDto + */ +export interface ActivityResponseDto { + /** + * + * @type {string} + * @memberof ActivityResponseDto + */ + assetId: string | null; + /** + * + * @type {string} + * @memberof ActivityResponseDto + */ + comment?: string | null; + /** + * + * @type {Date} + * @memberof ActivityResponseDto + */ + createdAt: Date; + /** + * + * @type {string} + * @memberof ActivityResponseDto + */ + id: string; + /** + * + * @type {string} + * @memberof ActivityResponseDto + */ + type: ActivityResponseDtoTypeEnum; + /** + * + * @type {UserDto} + * @memberof ActivityResponseDto + */ + user: UserDto; +} + + +/** + * @export + */ +export const ActivityResponseDtoTypeEnum = { + Comment: 'comment', + Like: 'like' +} as const; +export type ActivityResponseDtoTypeEnum = typeof ActivityResponseDtoTypeEnum[keyof typeof ActivityResponseDtoTypeEnum]; + + +/** + * Check if a given object implements the ActivityResponseDto interface. + */ +export function instanceOfActivityResponseDto(value: object): boolean { + let isInstance = true; + isInstance = isInstance && "assetId" in value; + isInstance = isInstance && "createdAt" in value; + isInstance = isInstance && "id" in value; + isInstance = isInstance && "type" in value; + isInstance = isInstance && "user" in value; + + return isInstance; +} + +export function ActivityResponseDtoFromJSON(json: any): ActivityResponseDto { + return ActivityResponseDtoFromJSONTyped(json, false); +} + +export function ActivityResponseDtoFromJSONTyped(json: any, ignoreDiscriminator: boolean): ActivityResponseDto { + if ((json === undefined) || (json === null)) { + return json; + } + return { + + 'assetId': json['assetId'], + 'comment': !exists(json, 'comment') ? undefined : json['comment'], + 'createdAt': (new Date(json['createdAt'])), + 'id': json['id'], + 'type': json['type'], + 'user': UserDtoFromJSON(json['user']), + }; +} + +export function ActivityResponseDtoToJSON(value?: ActivityResponseDto | null): any { + if (value === undefined) { + return undefined; + } + if (value === null) { + return null; + } + return { + + 'assetId': value.assetId, + 'comment': value.comment, + 'createdAt': (value.createdAt.toISOString()), + 'id': value.id, + 'type': value.type, + 'user': UserDtoToJSON(value.user), + }; +} + diff --git a/open-api/typescript-sdk/fetch-client/models/ActivityStatisticsResponseDto.ts b/open-api/typescript-sdk/fetch-client/models/ActivityStatisticsResponseDto.ts new file mode 100644 index 0000000000..21523f4167 --- /dev/null +++ b/open-api/typescript-sdk/fetch-client/models/ActivityStatisticsResponseDto.ts @@ -0,0 +1,66 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * Immich + * Immich API + * + * The version of the OpenAPI document: 1.94.1 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + +import { exists, mapValues } from '../runtime'; +/** + * + * @export + * @interface ActivityStatisticsResponseDto + */ +export interface ActivityStatisticsResponseDto { + /** + * + * @type {number} + * @memberof ActivityStatisticsResponseDto + */ + comments: number; +} + +/** + * Check if a given object implements the ActivityStatisticsResponseDto interface. + */ +export function instanceOfActivityStatisticsResponseDto(value: object): boolean { + let isInstance = true; + isInstance = isInstance && "comments" in value; + + return isInstance; +} + +export function ActivityStatisticsResponseDtoFromJSON(json: any): ActivityStatisticsResponseDto { + return ActivityStatisticsResponseDtoFromJSONTyped(json, false); +} + +export function ActivityStatisticsResponseDtoFromJSONTyped(json: any, ignoreDiscriminator: boolean): ActivityStatisticsResponseDto { + if ((json === undefined) || (json === null)) { + return json; + } + return { + + 'comments': json['comments'], + }; +} + +export function ActivityStatisticsResponseDtoToJSON(value?: ActivityStatisticsResponseDto | null): any { + if (value === undefined) { + return undefined; + } + if (value === null) { + return null; + } + return { + + 'comments': value.comments, + }; +} + diff --git a/open-api/typescript-sdk/fetch-client/models/AddUsersDto.ts b/open-api/typescript-sdk/fetch-client/models/AddUsersDto.ts new file mode 100644 index 0000000000..54f1857a0c --- /dev/null +++ b/open-api/typescript-sdk/fetch-client/models/AddUsersDto.ts @@ -0,0 +1,66 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * Immich + * Immich API + * + * The version of the OpenAPI document: 1.94.1 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + +import { exists, mapValues } from '../runtime'; +/** + * + * @export + * @interface AddUsersDto + */ +export interface AddUsersDto { + /** + * + * @type {Array} + * @memberof AddUsersDto + */ + sharedUserIds: Array; +} + +/** + * Check if a given object implements the AddUsersDto interface. + */ +export function instanceOfAddUsersDto(value: object): boolean { + let isInstance = true; + isInstance = isInstance && "sharedUserIds" in value; + + return isInstance; +} + +export function AddUsersDtoFromJSON(json: any): AddUsersDto { + return AddUsersDtoFromJSONTyped(json, false); +} + +export function AddUsersDtoFromJSONTyped(json: any, ignoreDiscriminator: boolean): AddUsersDto { + if ((json === undefined) || (json === null)) { + return json; + } + return { + + 'sharedUserIds': json['sharedUserIds'], + }; +} + +export function AddUsersDtoToJSON(value?: AddUsersDto | null): any { + if (value === undefined) { + return undefined; + } + if (value === null) { + return null; + } + return { + + 'sharedUserIds': value.sharedUserIds, + }; +} + diff --git a/open-api/typescript-sdk/fetch-client/models/AlbumCountResponseDto.ts b/open-api/typescript-sdk/fetch-client/models/AlbumCountResponseDto.ts new file mode 100644 index 0000000000..3ba3649a14 --- /dev/null +++ b/open-api/typescript-sdk/fetch-client/models/AlbumCountResponseDto.ts @@ -0,0 +1,84 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * Immich + * Immich API + * + * The version of the OpenAPI document: 1.94.1 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + +import { exists, mapValues } from '../runtime'; +/** + * + * @export + * @interface AlbumCountResponseDto + */ +export interface AlbumCountResponseDto { + /** + * + * @type {number} + * @memberof AlbumCountResponseDto + */ + notShared: number; + /** + * + * @type {number} + * @memberof AlbumCountResponseDto + */ + owned: number; + /** + * + * @type {number} + * @memberof AlbumCountResponseDto + */ + shared: number; +} + +/** + * Check if a given object implements the AlbumCountResponseDto interface. + */ +export function instanceOfAlbumCountResponseDto(value: object): boolean { + let isInstance = true; + isInstance = isInstance && "notShared" in value; + isInstance = isInstance && "owned" in value; + isInstance = isInstance && "shared" in value; + + return isInstance; +} + +export function AlbumCountResponseDtoFromJSON(json: any): AlbumCountResponseDto { + return AlbumCountResponseDtoFromJSONTyped(json, false); +} + +export function AlbumCountResponseDtoFromJSONTyped(json: any, ignoreDiscriminator: boolean): AlbumCountResponseDto { + if ((json === undefined) || (json === null)) { + return json; + } + return { + + 'notShared': json['notShared'], + 'owned': json['owned'], + 'shared': json['shared'], + }; +} + +export function AlbumCountResponseDtoToJSON(value?: AlbumCountResponseDto | null): any { + if (value === undefined) { + return undefined; + } + if (value === null) { + return null; + } + return { + + 'notShared': value.notShared, + 'owned': value.owned, + 'shared': value.shared, + }; +} + diff --git a/open-api/typescript-sdk/fetch-client/models/AlbumResponseDto.ts b/open-api/typescript-sdk/fetch-client/models/AlbumResponseDto.ts new file mode 100644 index 0000000000..af559f1584 --- /dev/null +++ b/open-api/typescript-sdk/fetch-client/models/AlbumResponseDto.ts @@ -0,0 +1,220 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * Immich + * Immich API + * + * The version of the OpenAPI document: 1.94.1 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + +import { exists, mapValues } from '../runtime'; +import type { AssetResponseDto } from './AssetResponseDto'; +import { + AssetResponseDtoFromJSON, + AssetResponseDtoFromJSONTyped, + AssetResponseDtoToJSON, +} from './AssetResponseDto'; +import type { UserResponseDto } from './UserResponseDto'; +import { + UserResponseDtoFromJSON, + UserResponseDtoFromJSONTyped, + UserResponseDtoToJSON, +} from './UserResponseDto'; + +/** + * + * @export + * @interface AlbumResponseDto + */ +export interface AlbumResponseDto { + /** + * + * @type {string} + * @memberof AlbumResponseDto + */ + albumName: string; + /** + * + * @type {string} + * @memberof AlbumResponseDto + */ + albumThumbnailAssetId: string | null; + /** + * + * @type {number} + * @memberof AlbumResponseDto + */ + assetCount: number; + /** + * + * @type {Array} + * @memberof AlbumResponseDto + */ + assets: Array; + /** + * + * @type {Date} + * @memberof AlbumResponseDto + */ + createdAt: Date; + /** + * + * @type {string} + * @memberof AlbumResponseDto + */ + description: string; + /** + * + * @type {Date} + * @memberof AlbumResponseDto + */ + endDate?: Date; + /** + * + * @type {boolean} + * @memberof AlbumResponseDto + */ + hasSharedLink: boolean; + /** + * + * @type {string} + * @memberof AlbumResponseDto + */ + id: string; + /** + * + * @type {boolean} + * @memberof AlbumResponseDto + */ + isActivityEnabled: boolean; + /** + * + * @type {Date} + * @memberof AlbumResponseDto + */ + lastModifiedAssetTimestamp?: Date; + /** + * + * @type {UserResponseDto} + * @memberof AlbumResponseDto + */ + owner: UserResponseDto; + /** + * + * @type {string} + * @memberof AlbumResponseDto + */ + ownerId: string; + /** + * + * @type {boolean} + * @memberof AlbumResponseDto + */ + shared: boolean; + /** + * + * @type {Array} + * @memberof AlbumResponseDto + */ + sharedUsers: Array; + /** + * + * @type {Date} + * @memberof AlbumResponseDto + */ + startDate?: Date; + /** + * + * @type {Date} + * @memberof AlbumResponseDto + */ + updatedAt: Date; +} + +/** + * Check if a given object implements the AlbumResponseDto interface. + */ +export function instanceOfAlbumResponseDto(value: object): boolean { + let isInstance = true; + isInstance = isInstance && "albumName" in value; + isInstance = isInstance && "albumThumbnailAssetId" in value; + isInstance = isInstance && "assetCount" in value; + isInstance = isInstance && "assets" in value; + isInstance = isInstance && "createdAt" in value; + isInstance = isInstance && "description" in value; + isInstance = isInstance && "hasSharedLink" in value; + isInstance = isInstance && "id" in value; + isInstance = isInstance && "isActivityEnabled" in value; + isInstance = isInstance && "owner" in value; + isInstance = isInstance && "ownerId" in value; + isInstance = isInstance && "shared" in value; + isInstance = isInstance && "sharedUsers" in value; + isInstance = isInstance && "updatedAt" in value; + + return isInstance; +} + +export function AlbumResponseDtoFromJSON(json: any): AlbumResponseDto { + return AlbumResponseDtoFromJSONTyped(json, false); +} + +export function AlbumResponseDtoFromJSONTyped(json: any, ignoreDiscriminator: boolean): AlbumResponseDto { + if ((json === undefined) || (json === null)) { + return json; + } + return { + + 'albumName': json['albumName'], + 'albumThumbnailAssetId': json['albumThumbnailAssetId'], + 'assetCount': json['assetCount'], + 'assets': ((json['assets'] as Array).map(AssetResponseDtoFromJSON)), + 'createdAt': (new Date(json['createdAt'])), + 'description': json['description'], + 'endDate': !exists(json, 'endDate') ? undefined : (new Date(json['endDate'])), + 'hasSharedLink': json['hasSharedLink'], + 'id': json['id'], + 'isActivityEnabled': json['isActivityEnabled'], + 'lastModifiedAssetTimestamp': !exists(json, 'lastModifiedAssetTimestamp') ? undefined : (new Date(json['lastModifiedAssetTimestamp'])), + 'owner': UserResponseDtoFromJSON(json['owner']), + 'ownerId': json['ownerId'], + 'shared': json['shared'], + 'sharedUsers': ((json['sharedUsers'] as Array).map(UserResponseDtoFromJSON)), + 'startDate': !exists(json, 'startDate') ? undefined : (new Date(json['startDate'])), + 'updatedAt': (new Date(json['updatedAt'])), + }; +} + +export function AlbumResponseDtoToJSON(value?: AlbumResponseDto | null): any { + if (value === undefined) { + return undefined; + } + if (value === null) { + return null; + } + return { + + 'albumName': value.albumName, + 'albumThumbnailAssetId': value.albumThumbnailAssetId, + 'assetCount': value.assetCount, + 'assets': ((value.assets as Array).map(AssetResponseDtoToJSON)), + 'createdAt': (value.createdAt.toISOString()), + 'description': value.description, + 'endDate': value.endDate === undefined ? undefined : (value.endDate.toISOString()), + 'hasSharedLink': value.hasSharedLink, + 'id': value.id, + 'isActivityEnabled': value.isActivityEnabled, + 'lastModifiedAssetTimestamp': value.lastModifiedAssetTimestamp === undefined ? undefined : (value.lastModifiedAssetTimestamp.toISOString()), + 'owner': UserResponseDtoToJSON(value.owner), + 'ownerId': value.ownerId, + 'shared': value.shared, + 'sharedUsers': ((value.sharedUsers as Array).map(UserResponseDtoToJSON)), + 'startDate': value.startDate === undefined ? undefined : (value.startDate.toISOString()), + 'updatedAt': (value.updatedAt.toISOString()), + }; +} + diff --git a/open-api/typescript-sdk/fetch-client/models/AllJobStatusResponseDto.ts b/open-api/typescript-sdk/fetch-client/models/AllJobStatusResponseDto.ts new file mode 100644 index 0000000000..69cdb72f65 --- /dev/null +++ b/open-api/typescript-sdk/fetch-client/models/AllJobStatusResponseDto.ts @@ -0,0 +1,172 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * Immich + * Immich API + * + * The version of the OpenAPI document: 1.94.1 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + +import { exists, mapValues } from '../runtime'; +import type { JobStatusDto } from './JobStatusDto'; +import { + JobStatusDtoFromJSON, + JobStatusDtoFromJSONTyped, + JobStatusDtoToJSON, +} from './JobStatusDto'; + +/** + * + * @export + * @interface AllJobStatusResponseDto + */ +export interface AllJobStatusResponseDto { + /** + * + * @type {JobStatusDto} + * @memberof AllJobStatusResponseDto + */ + backgroundTask: JobStatusDto; + /** + * + * @type {JobStatusDto} + * @memberof AllJobStatusResponseDto + */ + faceDetection: JobStatusDto; + /** + * + * @type {JobStatusDto} + * @memberof AllJobStatusResponseDto + */ + facialRecognition: JobStatusDto; + /** + * + * @type {JobStatusDto} + * @memberof AllJobStatusResponseDto + */ + library: JobStatusDto; + /** + * + * @type {JobStatusDto} + * @memberof AllJobStatusResponseDto + */ + metadataExtraction: JobStatusDto; + /** + * + * @type {JobStatusDto} + * @memberof AllJobStatusResponseDto + */ + migration: JobStatusDto; + /** + * + * @type {JobStatusDto} + * @memberof AllJobStatusResponseDto + */ + search: JobStatusDto; + /** + * + * @type {JobStatusDto} + * @memberof AllJobStatusResponseDto + */ + sidecar: JobStatusDto; + /** + * + * @type {JobStatusDto} + * @memberof AllJobStatusResponseDto + */ + smartSearch: JobStatusDto; + /** + * + * @type {JobStatusDto} + * @memberof AllJobStatusResponseDto + */ + storageTemplateMigration: JobStatusDto; + /** + * + * @type {JobStatusDto} + * @memberof AllJobStatusResponseDto + */ + thumbnailGeneration: JobStatusDto; + /** + * + * @type {JobStatusDto} + * @memberof AllJobStatusResponseDto + */ + videoConversion: JobStatusDto; +} + +/** + * Check if a given object implements the AllJobStatusResponseDto interface. + */ +export function instanceOfAllJobStatusResponseDto(value: object): boolean { + let isInstance = true; + isInstance = isInstance && "backgroundTask" in value; + isInstance = isInstance && "faceDetection" in value; + isInstance = isInstance && "facialRecognition" in value; + isInstance = isInstance && "library" in value; + isInstance = isInstance && "metadataExtraction" in value; + isInstance = isInstance && "migration" in value; + isInstance = isInstance && "search" in value; + isInstance = isInstance && "sidecar" in value; + isInstance = isInstance && "smartSearch" in value; + isInstance = isInstance && "storageTemplateMigration" in value; + isInstance = isInstance && "thumbnailGeneration" in value; + isInstance = isInstance && "videoConversion" in value; + + return isInstance; +} + +export function AllJobStatusResponseDtoFromJSON(json: any): AllJobStatusResponseDto { + return AllJobStatusResponseDtoFromJSONTyped(json, false); +} + +export function AllJobStatusResponseDtoFromJSONTyped(json: any, ignoreDiscriminator: boolean): AllJobStatusResponseDto { + if ((json === undefined) || (json === null)) { + return json; + } + return { + + 'backgroundTask': JobStatusDtoFromJSON(json['backgroundTask']), + 'faceDetection': JobStatusDtoFromJSON(json['faceDetection']), + 'facialRecognition': JobStatusDtoFromJSON(json['facialRecognition']), + 'library': JobStatusDtoFromJSON(json['library']), + 'metadataExtraction': JobStatusDtoFromJSON(json['metadataExtraction']), + 'migration': JobStatusDtoFromJSON(json['migration']), + 'search': JobStatusDtoFromJSON(json['search']), + 'sidecar': JobStatusDtoFromJSON(json['sidecar']), + 'smartSearch': JobStatusDtoFromJSON(json['smartSearch']), + 'storageTemplateMigration': JobStatusDtoFromJSON(json['storageTemplateMigration']), + 'thumbnailGeneration': JobStatusDtoFromJSON(json['thumbnailGeneration']), + 'videoConversion': JobStatusDtoFromJSON(json['videoConversion']), + }; +} + +export function AllJobStatusResponseDtoToJSON(value?: AllJobStatusResponseDto | null): any { + if (value === undefined) { + return undefined; + } + if (value === null) { + return null; + } + return { + + 'backgroundTask': JobStatusDtoToJSON(value.backgroundTask), + 'faceDetection': JobStatusDtoToJSON(value.faceDetection), + 'facialRecognition': JobStatusDtoToJSON(value.facialRecognition), + 'library': JobStatusDtoToJSON(value.library), + 'metadataExtraction': JobStatusDtoToJSON(value.metadataExtraction), + 'migration': JobStatusDtoToJSON(value.migration), + 'search': JobStatusDtoToJSON(value.search), + 'sidecar': JobStatusDtoToJSON(value.sidecar), + 'smartSearch': JobStatusDtoToJSON(value.smartSearch), + 'storageTemplateMigration': JobStatusDtoToJSON(value.storageTemplateMigration), + 'thumbnailGeneration': JobStatusDtoToJSON(value.thumbnailGeneration), + 'videoConversion': JobStatusDtoToJSON(value.videoConversion), + }; +} + diff --git a/open-api/typescript-sdk/fetch-client/models/AssetBulkDeleteDto.ts b/open-api/typescript-sdk/fetch-client/models/AssetBulkDeleteDto.ts new file mode 100644 index 0000000000..d11f7f0632 --- /dev/null +++ b/open-api/typescript-sdk/fetch-client/models/AssetBulkDeleteDto.ts @@ -0,0 +1,74 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * Immich + * Immich API + * + * The version of the OpenAPI document: 1.94.1 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + +import { exists, mapValues } from '../runtime'; +/** + * + * @export + * @interface AssetBulkDeleteDto + */ +export interface AssetBulkDeleteDto { + /** + * + * @type {boolean} + * @memberof AssetBulkDeleteDto + */ + force?: boolean; + /** + * + * @type {Array} + * @memberof AssetBulkDeleteDto + */ + ids: Array; +} + +/** + * Check if a given object implements the AssetBulkDeleteDto interface. + */ +export function instanceOfAssetBulkDeleteDto(value: object): boolean { + let isInstance = true; + isInstance = isInstance && "ids" in value; + + return isInstance; +} + +export function AssetBulkDeleteDtoFromJSON(json: any): AssetBulkDeleteDto { + return AssetBulkDeleteDtoFromJSONTyped(json, false); +} + +export function AssetBulkDeleteDtoFromJSONTyped(json: any, ignoreDiscriminator: boolean): AssetBulkDeleteDto { + if ((json === undefined) || (json === null)) { + return json; + } + return { + + 'force': !exists(json, 'force') ? undefined : json['force'], + 'ids': json['ids'], + }; +} + +export function AssetBulkDeleteDtoToJSON(value?: AssetBulkDeleteDto | null): any { + if (value === undefined) { + return undefined; + } + if (value === null) { + return null; + } + return { + + 'force': value.force, + 'ids': value.ids, + }; +} + diff --git a/open-api/typescript-sdk/fetch-client/models/AssetBulkUpdateDto.ts b/open-api/typescript-sdk/fetch-client/models/AssetBulkUpdateDto.ts new file mode 100644 index 0000000000..53fedefba4 --- /dev/null +++ b/open-api/typescript-sdk/fetch-client/models/AssetBulkUpdateDto.ts @@ -0,0 +1,122 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * Immich + * Immich API + * + * The version of the OpenAPI document: 1.94.1 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + +import { exists, mapValues } from '../runtime'; +/** + * + * @export + * @interface AssetBulkUpdateDto + */ +export interface AssetBulkUpdateDto { + /** + * + * @type {string} + * @memberof AssetBulkUpdateDto + */ + dateTimeOriginal?: string; + /** + * + * @type {Array} + * @memberof AssetBulkUpdateDto + */ + ids: Array; + /** + * + * @type {boolean} + * @memberof AssetBulkUpdateDto + */ + isArchived?: boolean; + /** + * + * @type {boolean} + * @memberof AssetBulkUpdateDto + */ + isFavorite?: boolean; + /** + * + * @type {number} + * @memberof AssetBulkUpdateDto + */ + latitude?: number; + /** + * + * @type {number} + * @memberof AssetBulkUpdateDto + */ + longitude?: number; + /** + * + * @type {boolean} + * @memberof AssetBulkUpdateDto + */ + removeParent?: boolean; + /** + * + * @type {string} + * @memberof AssetBulkUpdateDto + */ + stackParentId?: string; +} + +/** + * Check if a given object implements the AssetBulkUpdateDto interface. + */ +export function instanceOfAssetBulkUpdateDto(value: object): boolean { + let isInstance = true; + isInstance = isInstance && "ids" in value; + + return isInstance; +} + +export function AssetBulkUpdateDtoFromJSON(json: any): AssetBulkUpdateDto { + return AssetBulkUpdateDtoFromJSONTyped(json, false); +} + +export function AssetBulkUpdateDtoFromJSONTyped(json: any, ignoreDiscriminator: boolean): AssetBulkUpdateDto { + if ((json === undefined) || (json === null)) { + return json; + } + return { + + 'dateTimeOriginal': !exists(json, 'dateTimeOriginal') ? undefined : json['dateTimeOriginal'], + 'ids': json['ids'], + 'isArchived': !exists(json, 'isArchived') ? undefined : json['isArchived'], + 'isFavorite': !exists(json, 'isFavorite') ? undefined : json['isFavorite'], + 'latitude': !exists(json, 'latitude') ? undefined : json['latitude'], + 'longitude': !exists(json, 'longitude') ? undefined : json['longitude'], + 'removeParent': !exists(json, 'removeParent') ? undefined : json['removeParent'], + 'stackParentId': !exists(json, 'stackParentId') ? undefined : json['stackParentId'], + }; +} + +export function AssetBulkUpdateDtoToJSON(value?: AssetBulkUpdateDto | null): any { + if (value === undefined) { + return undefined; + } + if (value === null) { + return null; + } + return { + + 'dateTimeOriginal': value.dateTimeOriginal, + 'ids': value.ids, + 'isArchived': value.isArchived, + 'isFavorite': value.isFavorite, + 'latitude': value.latitude, + 'longitude': value.longitude, + 'removeParent': value.removeParent, + 'stackParentId': value.stackParentId, + }; +} + diff --git a/open-api/typescript-sdk/fetch-client/models/AssetBulkUploadCheckDto.ts b/open-api/typescript-sdk/fetch-client/models/AssetBulkUploadCheckDto.ts new file mode 100644 index 0000000000..0e509e24ce --- /dev/null +++ b/open-api/typescript-sdk/fetch-client/models/AssetBulkUploadCheckDto.ts @@ -0,0 +1,73 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * Immich + * Immich API + * + * The version of the OpenAPI document: 1.94.1 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + +import { exists, mapValues } from '../runtime'; +import type { AssetBulkUploadCheckItem } from './AssetBulkUploadCheckItem'; +import { + AssetBulkUploadCheckItemFromJSON, + AssetBulkUploadCheckItemFromJSONTyped, + AssetBulkUploadCheckItemToJSON, +} from './AssetBulkUploadCheckItem'; + +/** + * + * @export + * @interface AssetBulkUploadCheckDto + */ +export interface AssetBulkUploadCheckDto { + /** + * + * @type {Array} + * @memberof AssetBulkUploadCheckDto + */ + assets: Array; +} + +/** + * Check if a given object implements the AssetBulkUploadCheckDto interface. + */ +export function instanceOfAssetBulkUploadCheckDto(value: object): boolean { + let isInstance = true; + isInstance = isInstance && "assets" in value; + + return isInstance; +} + +export function AssetBulkUploadCheckDtoFromJSON(json: any): AssetBulkUploadCheckDto { + return AssetBulkUploadCheckDtoFromJSONTyped(json, false); +} + +export function AssetBulkUploadCheckDtoFromJSONTyped(json: any, ignoreDiscriminator: boolean): AssetBulkUploadCheckDto { + if ((json === undefined) || (json === null)) { + return json; + } + return { + + 'assets': ((json['assets'] as Array).map(AssetBulkUploadCheckItemFromJSON)), + }; +} + +export function AssetBulkUploadCheckDtoToJSON(value?: AssetBulkUploadCheckDto | null): any { + if (value === undefined) { + return undefined; + } + if (value === null) { + return null; + } + return { + + 'assets': ((value.assets as Array).map(AssetBulkUploadCheckItemToJSON)), + }; +} + diff --git a/open-api/typescript-sdk/fetch-client/models/AssetBulkUploadCheckItem.ts b/open-api/typescript-sdk/fetch-client/models/AssetBulkUploadCheckItem.ts new file mode 100644 index 0000000000..6fc8bb09cf --- /dev/null +++ b/open-api/typescript-sdk/fetch-client/models/AssetBulkUploadCheckItem.ts @@ -0,0 +1,75 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * Immich + * Immich API + * + * The version of the OpenAPI document: 1.94.1 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + +import { exists, mapValues } from '../runtime'; +/** + * + * @export + * @interface AssetBulkUploadCheckItem + */ +export interface AssetBulkUploadCheckItem { + /** + * base64 or hex encoded sha1 hash + * @type {string} + * @memberof AssetBulkUploadCheckItem + */ + checksum: string; + /** + * + * @type {string} + * @memberof AssetBulkUploadCheckItem + */ + id: string; +} + +/** + * Check if a given object implements the AssetBulkUploadCheckItem interface. + */ +export function instanceOfAssetBulkUploadCheckItem(value: object): boolean { + let isInstance = true; + isInstance = isInstance && "checksum" in value; + isInstance = isInstance && "id" in value; + + return isInstance; +} + +export function AssetBulkUploadCheckItemFromJSON(json: any): AssetBulkUploadCheckItem { + return AssetBulkUploadCheckItemFromJSONTyped(json, false); +} + +export function AssetBulkUploadCheckItemFromJSONTyped(json: any, ignoreDiscriminator: boolean): AssetBulkUploadCheckItem { + if ((json === undefined) || (json === null)) { + return json; + } + return { + + 'checksum': json['checksum'], + 'id': json['id'], + }; +} + +export function AssetBulkUploadCheckItemToJSON(value?: AssetBulkUploadCheckItem | null): any { + if (value === undefined) { + return undefined; + } + if (value === null) { + return null; + } + return { + + 'checksum': value.checksum, + 'id': value.id, + }; +} + diff --git a/open-api/typescript-sdk/fetch-client/models/AssetBulkUploadCheckResponseDto.ts b/open-api/typescript-sdk/fetch-client/models/AssetBulkUploadCheckResponseDto.ts new file mode 100644 index 0000000000..caa6e62374 --- /dev/null +++ b/open-api/typescript-sdk/fetch-client/models/AssetBulkUploadCheckResponseDto.ts @@ -0,0 +1,73 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * Immich + * Immich API + * + * The version of the OpenAPI document: 1.94.1 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + +import { exists, mapValues } from '../runtime'; +import type { AssetBulkUploadCheckResult } from './AssetBulkUploadCheckResult'; +import { + AssetBulkUploadCheckResultFromJSON, + AssetBulkUploadCheckResultFromJSONTyped, + AssetBulkUploadCheckResultToJSON, +} from './AssetBulkUploadCheckResult'; + +/** + * + * @export + * @interface AssetBulkUploadCheckResponseDto + */ +export interface AssetBulkUploadCheckResponseDto { + /** + * + * @type {Array} + * @memberof AssetBulkUploadCheckResponseDto + */ + results: Array; +} + +/** + * Check if a given object implements the AssetBulkUploadCheckResponseDto interface. + */ +export function instanceOfAssetBulkUploadCheckResponseDto(value: object): boolean { + let isInstance = true; + isInstance = isInstance && "results" in value; + + return isInstance; +} + +export function AssetBulkUploadCheckResponseDtoFromJSON(json: any): AssetBulkUploadCheckResponseDto { + return AssetBulkUploadCheckResponseDtoFromJSONTyped(json, false); +} + +export function AssetBulkUploadCheckResponseDtoFromJSONTyped(json: any, ignoreDiscriminator: boolean): AssetBulkUploadCheckResponseDto { + if ((json === undefined) || (json === null)) { + return json; + } + return { + + 'results': ((json['results'] as Array).map(AssetBulkUploadCheckResultFromJSON)), + }; +} + +export function AssetBulkUploadCheckResponseDtoToJSON(value?: AssetBulkUploadCheckResponseDto | null): any { + if (value === undefined) { + return undefined; + } + if (value === null) { + return null; + } + return { + + 'results': ((value.results as Array).map(AssetBulkUploadCheckResultToJSON)), + }; +} + diff --git a/open-api/typescript-sdk/fetch-client/models/AssetBulkUploadCheckResult.ts b/open-api/typescript-sdk/fetch-client/models/AssetBulkUploadCheckResult.ts new file mode 100644 index 0000000000..ad106b2723 --- /dev/null +++ b/open-api/typescript-sdk/fetch-client/models/AssetBulkUploadCheckResult.ts @@ -0,0 +1,111 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * Immich + * Immich API + * + * The version of the OpenAPI document: 1.94.1 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + +import { exists, mapValues } from '../runtime'; +/** + * + * @export + * @interface AssetBulkUploadCheckResult + */ +export interface AssetBulkUploadCheckResult { + /** + * + * @type {string} + * @memberof AssetBulkUploadCheckResult + */ + action: AssetBulkUploadCheckResultActionEnum; + /** + * + * @type {string} + * @memberof AssetBulkUploadCheckResult + */ + assetId?: string; + /** + * + * @type {string} + * @memberof AssetBulkUploadCheckResult + */ + id: string; + /** + * + * @type {string} + * @memberof AssetBulkUploadCheckResult + */ + reason?: AssetBulkUploadCheckResultReasonEnum; +} + + +/** + * @export + */ +export const AssetBulkUploadCheckResultActionEnum = { + Accept: 'accept', + Reject: 'reject' +} as const; +export type AssetBulkUploadCheckResultActionEnum = typeof AssetBulkUploadCheckResultActionEnum[keyof typeof AssetBulkUploadCheckResultActionEnum]; + +/** + * @export + */ +export const AssetBulkUploadCheckResultReasonEnum = { + Duplicate: 'duplicate', + UnsupportedFormat: 'unsupported-format' +} as const; +export type AssetBulkUploadCheckResultReasonEnum = typeof AssetBulkUploadCheckResultReasonEnum[keyof typeof AssetBulkUploadCheckResultReasonEnum]; + + +/** + * Check if a given object implements the AssetBulkUploadCheckResult interface. + */ +export function instanceOfAssetBulkUploadCheckResult(value: object): boolean { + let isInstance = true; + isInstance = isInstance && "action" in value; + isInstance = isInstance && "id" in value; + + return isInstance; +} + +export function AssetBulkUploadCheckResultFromJSON(json: any): AssetBulkUploadCheckResult { + return AssetBulkUploadCheckResultFromJSONTyped(json, false); +} + +export function AssetBulkUploadCheckResultFromJSONTyped(json: any, ignoreDiscriminator: boolean): AssetBulkUploadCheckResult { + if ((json === undefined) || (json === null)) { + return json; + } + return { + + 'action': json['action'], + 'assetId': !exists(json, 'assetId') ? undefined : json['assetId'], + 'id': json['id'], + 'reason': !exists(json, 'reason') ? undefined : json['reason'], + }; +} + +export function AssetBulkUploadCheckResultToJSON(value?: AssetBulkUploadCheckResult | null): any { + if (value === undefined) { + return undefined; + } + if (value === null) { + return null; + } + return { + + 'action': value.action, + 'assetId': value.assetId, + 'id': value.id, + 'reason': value.reason, + }; +} + diff --git a/open-api/typescript-sdk/fetch-client/models/AssetFaceResponseDto.ts b/open-api/typescript-sdk/fetch-client/models/AssetFaceResponseDto.ts new file mode 100644 index 0000000000..e4a34b512c --- /dev/null +++ b/open-api/typescript-sdk/fetch-client/models/AssetFaceResponseDto.ts @@ -0,0 +1,136 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * Immich + * Immich API + * + * The version of the OpenAPI document: 1.94.1 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + +import { exists, mapValues } from '../runtime'; +import type { PersonResponseDto } from './PersonResponseDto'; +import { + PersonResponseDtoFromJSON, + PersonResponseDtoFromJSONTyped, + PersonResponseDtoToJSON, +} from './PersonResponseDto'; + +/** + * + * @export + * @interface AssetFaceResponseDto + */ +export interface AssetFaceResponseDto { + /** + * + * @type {number} + * @memberof AssetFaceResponseDto + */ + boundingBoxX1: number; + /** + * + * @type {number} + * @memberof AssetFaceResponseDto + */ + boundingBoxX2: number; + /** + * + * @type {number} + * @memberof AssetFaceResponseDto + */ + boundingBoxY1: number; + /** + * + * @type {number} + * @memberof AssetFaceResponseDto + */ + boundingBoxY2: number; + /** + * + * @type {string} + * @memberof AssetFaceResponseDto + */ + id: string; + /** + * + * @type {number} + * @memberof AssetFaceResponseDto + */ + imageHeight: number; + /** + * + * @type {number} + * @memberof AssetFaceResponseDto + */ + imageWidth: number; + /** + * + * @type {PersonResponseDto} + * @memberof AssetFaceResponseDto + */ + person: PersonResponseDto | null; +} + +/** + * Check if a given object implements the AssetFaceResponseDto interface. + */ +export function instanceOfAssetFaceResponseDto(value: object): boolean { + let isInstance = true; + isInstance = isInstance && "boundingBoxX1" in value; + isInstance = isInstance && "boundingBoxX2" in value; + isInstance = isInstance && "boundingBoxY1" in value; + isInstance = isInstance && "boundingBoxY2" in value; + isInstance = isInstance && "id" in value; + isInstance = isInstance && "imageHeight" in value; + isInstance = isInstance && "imageWidth" in value; + isInstance = isInstance && "person" in value; + + return isInstance; +} + +export function AssetFaceResponseDtoFromJSON(json: any): AssetFaceResponseDto { + return AssetFaceResponseDtoFromJSONTyped(json, false); +} + +export function AssetFaceResponseDtoFromJSONTyped(json: any, ignoreDiscriminator: boolean): AssetFaceResponseDto { + if ((json === undefined) || (json === null)) { + return json; + } + return { + + 'boundingBoxX1': json['boundingBoxX1'], + 'boundingBoxX2': json['boundingBoxX2'], + 'boundingBoxY1': json['boundingBoxY1'], + 'boundingBoxY2': json['boundingBoxY2'], + 'id': json['id'], + 'imageHeight': json['imageHeight'], + 'imageWidth': json['imageWidth'], + 'person': PersonResponseDtoFromJSON(json['person']), + }; +} + +export function AssetFaceResponseDtoToJSON(value?: AssetFaceResponseDto | null): any { + if (value === undefined) { + return undefined; + } + if (value === null) { + return null; + } + return { + + 'boundingBoxX1': value.boundingBoxX1, + 'boundingBoxX2': value.boundingBoxX2, + 'boundingBoxY1': value.boundingBoxY1, + 'boundingBoxY2': value.boundingBoxY2, + 'id': value.id, + 'imageHeight': value.imageHeight, + 'imageWidth': value.imageWidth, + 'person': PersonResponseDtoToJSON(value.person), + }; +} + diff --git a/open-api/typescript-sdk/fetch-client/models/AssetFaceUpdateDto.ts b/open-api/typescript-sdk/fetch-client/models/AssetFaceUpdateDto.ts new file mode 100644 index 0000000000..4aac731fdd --- /dev/null +++ b/open-api/typescript-sdk/fetch-client/models/AssetFaceUpdateDto.ts @@ -0,0 +1,73 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * Immich + * Immich API + * + * The version of the OpenAPI document: 1.94.1 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + +import { exists, mapValues } from '../runtime'; +import type { AssetFaceUpdateItem } from './AssetFaceUpdateItem'; +import { + AssetFaceUpdateItemFromJSON, + AssetFaceUpdateItemFromJSONTyped, + AssetFaceUpdateItemToJSON, +} from './AssetFaceUpdateItem'; + +/** + * + * @export + * @interface AssetFaceUpdateDto + */ +export interface AssetFaceUpdateDto { + /** + * + * @type {Array} + * @memberof AssetFaceUpdateDto + */ + data: Array; +} + +/** + * Check if a given object implements the AssetFaceUpdateDto interface. + */ +export function instanceOfAssetFaceUpdateDto(value: object): boolean { + let isInstance = true; + isInstance = isInstance && "data" in value; + + return isInstance; +} + +export function AssetFaceUpdateDtoFromJSON(json: any): AssetFaceUpdateDto { + return AssetFaceUpdateDtoFromJSONTyped(json, false); +} + +export function AssetFaceUpdateDtoFromJSONTyped(json: any, ignoreDiscriminator: boolean): AssetFaceUpdateDto { + if ((json === undefined) || (json === null)) { + return json; + } + return { + + 'data': ((json['data'] as Array).map(AssetFaceUpdateItemFromJSON)), + }; +} + +export function AssetFaceUpdateDtoToJSON(value?: AssetFaceUpdateDto | null): any { + if (value === undefined) { + return undefined; + } + if (value === null) { + return null; + } + return { + + 'data': ((value.data as Array).map(AssetFaceUpdateItemToJSON)), + }; +} + diff --git a/open-api/typescript-sdk/fetch-client/models/AssetFaceUpdateItem.ts b/open-api/typescript-sdk/fetch-client/models/AssetFaceUpdateItem.ts new file mode 100644 index 0000000000..14637b5205 --- /dev/null +++ b/open-api/typescript-sdk/fetch-client/models/AssetFaceUpdateItem.ts @@ -0,0 +1,75 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * Immich + * Immich API + * + * The version of the OpenAPI document: 1.94.1 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + +import { exists, mapValues } from '../runtime'; +/** + * + * @export + * @interface AssetFaceUpdateItem + */ +export interface AssetFaceUpdateItem { + /** + * + * @type {string} + * @memberof AssetFaceUpdateItem + */ + assetId: string; + /** + * + * @type {string} + * @memberof AssetFaceUpdateItem + */ + personId: string; +} + +/** + * Check if a given object implements the AssetFaceUpdateItem interface. + */ +export function instanceOfAssetFaceUpdateItem(value: object): boolean { + let isInstance = true; + isInstance = isInstance && "assetId" in value; + isInstance = isInstance && "personId" in value; + + return isInstance; +} + +export function AssetFaceUpdateItemFromJSON(json: any): AssetFaceUpdateItem { + return AssetFaceUpdateItemFromJSONTyped(json, false); +} + +export function AssetFaceUpdateItemFromJSONTyped(json: any, ignoreDiscriminator: boolean): AssetFaceUpdateItem { + if ((json === undefined) || (json === null)) { + return json; + } + return { + + 'assetId': json['assetId'], + 'personId': json['personId'], + }; +} + +export function AssetFaceUpdateItemToJSON(value?: AssetFaceUpdateItem | null): any { + if (value === undefined) { + return undefined; + } + if (value === null) { + return null; + } + return { + + 'assetId': value.assetId, + 'personId': value.personId, + }; +} + diff --git a/open-api/typescript-sdk/fetch-client/models/AssetFaceWithoutPersonResponseDto.ts b/open-api/typescript-sdk/fetch-client/models/AssetFaceWithoutPersonResponseDto.ts new file mode 100644 index 0000000000..b84e7893c0 --- /dev/null +++ b/open-api/typescript-sdk/fetch-client/models/AssetFaceWithoutPersonResponseDto.ts @@ -0,0 +1,120 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * Immich + * Immich API + * + * The version of the OpenAPI document: 1.94.1 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + +import { exists, mapValues } from '../runtime'; +/** + * + * @export + * @interface AssetFaceWithoutPersonResponseDto + */ +export interface AssetFaceWithoutPersonResponseDto { + /** + * + * @type {number} + * @memberof AssetFaceWithoutPersonResponseDto + */ + boundingBoxX1: number; + /** + * + * @type {number} + * @memberof AssetFaceWithoutPersonResponseDto + */ + boundingBoxX2: number; + /** + * + * @type {number} + * @memberof AssetFaceWithoutPersonResponseDto + */ + boundingBoxY1: number; + /** + * + * @type {number} + * @memberof AssetFaceWithoutPersonResponseDto + */ + boundingBoxY2: number; + /** + * + * @type {string} + * @memberof AssetFaceWithoutPersonResponseDto + */ + id: string; + /** + * + * @type {number} + * @memberof AssetFaceWithoutPersonResponseDto + */ + imageHeight: number; + /** + * + * @type {number} + * @memberof AssetFaceWithoutPersonResponseDto + */ + imageWidth: number; +} + +/** + * Check if a given object implements the AssetFaceWithoutPersonResponseDto interface. + */ +export function instanceOfAssetFaceWithoutPersonResponseDto(value: object): boolean { + let isInstance = true; + isInstance = isInstance && "boundingBoxX1" in value; + isInstance = isInstance && "boundingBoxX2" in value; + isInstance = isInstance && "boundingBoxY1" in value; + isInstance = isInstance && "boundingBoxY2" in value; + isInstance = isInstance && "id" in value; + isInstance = isInstance && "imageHeight" in value; + isInstance = isInstance && "imageWidth" in value; + + return isInstance; +} + +export function AssetFaceWithoutPersonResponseDtoFromJSON(json: any): AssetFaceWithoutPersonResponseDto { + return AssetFaceWithoutPersonResponseDtoFromJSONTyped(json, false); +} + +export function AssetFaceWithoutPersonResponseDtoFromJSONTyped(json: any, ignoreDiscriminator: boolean): AssetFaceWithoutPersonResponseDto { + if ((json === undefined) || (json === null)) { + return json; + } + return { + + 'boundingBoxX1': json['boundingBoxX1'], + 'boundingBoxX2': json['boundingBoxX2'], + 'boundingBoxY1': json['boundingBoxY1'], + 'boundingBoxY2': json['boundingBoxY2'], + 'id': json['id'], + 'imageHeight': json['imageHeight'], + 'imageWidth': json['imageWidth'], + }; +} + +export function AssetFaceWithoutPersonResponseDtoToJSON(value?: AssetFaceWithoutPersonResponseDto | null): any { + if (value === undefined) { + return undefined; + } + if (value === null) { + return null; + } + return { + + 'boundingBoxX1': value.boundingBoxX1, + 'boundingBoxX2': value.boundingBoxX2, + 'boundingBoxY1': value.boundingBoxY1, + 'boundingBoxY2': value.boundingBoxY2, + 'id': value.id, + 'imageHeight': value.imageHeight, + 'imageWidth': value.imageWidth, + }; +} + diff --git a/open-api/typescript-sdk/fetch-client/models/AssetFileUploadResponseDto.ts b/open-api/typescript-sdk/fetch-client/models/AssetFileUploadResponseDto.ts new file mode 100644 index 0000000000..53155c930d --- /dev/null +++ b/open-api/typescript-sdk/fetch-client/models/AssetFileUploadResponseDto.ts @@ -0,0 +1,75 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * Immich + * Immich API + * + * The version of the OpenAPI document: 1.94.1 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + +import { exists, mapValues } from '../runtime'; +/** + * + * @export + * @interface AssetFileUploadResponseDto + */ +export interface AssetFileUploadResponseDto { + /** + * + * @type {boolean} + * @memberof AssetFileUploadResponseDto + */ + duplicate: boolean; + /** + * + * @type {string} + * @memberof AssetFileUploadResponseDto + */ + id: string; +} + +/** + * Check if a given object implements the AssetFileUploadResponseDto interface. + */ +export function instanceOfAssetFileUploadResponseDto(value: object): boolean { + let isInstance = true; + isInstance = isInstance && "duplicate" in value; + isInstance = isInstance && "id" in value; + + return isInstance; +} + +export function AssetFileUploadResponseDtoFromJSON(json: any): AssetFileUploadResponseDto { + return AssetFileUploadResponseDtoFromJSONTyped(json, false); +} + +export function AssetFileUploadResponseDtoFromJSONTyped(json: any, ignoreDiscriminator: boolean): AssetFileUploadResponseDto { + if ((json === undefined) || (json === null)) { + return json; + } + return { + + 'duplicate': json['duplicate'], + 'id': json['id'], + }; +} + +export function AssetFileUploadResponseDtoToJSON(value?: AssetFileUploadResponseDto | null): any { + if (value === undefined) { + return undefined; + } + if (value === null) { + return null; + } + return { + + 'duplicate': value.duplicate, + 'id': value.id, + }; +} + diff --git a/open-api/typescript-sdk/fetch-client/models/AssetIdsDto.ts b/open-api/typescript-sdk/fetch-client/models/AssetIdsDto.ts new file mode 100644 index 0000000000..ad33322ea3 --- /dev/null +++ b/open-api/typescript-sdk/fetch-client/models/AssetIdsDto.ts @@ -0,0 +1,66 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * Immich + * Immich API + * + * The version of the OpenAPI document: 1.94.1 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + +import { exists, mapValues } from '../runtime'; +/** + * + * @export + * @interface AssetIdsDto + */ +export interface AssetIdsDto { + /** + * + * @type {Array} + * @memberof AssetIdsDto + */ + assetIds: Array; +} + +/** + * Check if a given object implements the AssetIdsDto interface. + */ +export function instanceOfAssetIdsDto(value: object): boolean { + let isInstance = true; + isInstance = isInstance && "assetIds" in value; + + return isInstance; +} + +export function AssetIdsDtoFromJSON(json: any): AssetIdsDto { + return AssetIdsDtoFromJSONTyped(json, false); +} + +export function AssetIdsDtoFromJSONTyped(json: any, ignoreDiscriminator: boolean): AssetIdsDto { + if ((json === undefined) || (json === null)) { + return json; + } + return { + + 'assetIds': json['assetIds'], + }; +} + +export function AssetIdsDtoToJSON(value?: AssetIdsDto | null): any { + if (value === undefined) { + return undefined; + } + if (value === null) { + return null; + } + return { + + 'assetIds': value.assetIds, + }; +} + diff --git a/open-api/typescript-sdk/fetch-client/models/AssetIdsResponseDto.ts b/open-api/typescript-sdk/fetch-client/models/AssetIdsResponseDto.ts new file mode 100644 index 0000000000..5e6ba5a5b0 --- /dev/null +++ b/open-api/typescript-sdk/fetch-client/models/AssetIdsResponseDto.ts @@ -0,0 +1,95 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * Immich + * Immich API + * + * The version of the OpenAPI document: 1.94.1 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + +import { exists, mapValues } from '../runtime'; +/** + * + * @export + * @interface AssetIdsResponseDto + */ +export interface AssetIdsResponseDto { + /** + * + * @type {string} + * @memberof AssetIdsResponseDto + */ + assetId: string; + /** + * + * @type {string} + * @memberof AssetIdsResponseDto + */ + error?: AssetIdsResponseDtoErrorEnum; + /** + * + * @type {boolean} + * @memberof AssetIdsResponseDto + */ + success: boolean; +} + + +/** + * @export + */ +export const AssetIdsResponseDtoErrorEnum = { + Duplicate: 'duplicate', + NoPermission: 'no_permission', + NotFound: 'not_found' +} as const; +export type AssetIdsResponseDtoErrorEnum = typeof AssetIdsResponseDtoErrorEnum[keyof typeof AssetIdsResponseDtoErrorEnum]; + + +/** + * Check if a given object implements the AssetIdsResponseDto interface. + */ +export function instanceOfAssetIdsResponseDto(value: object): boolean { + let isInstance = true; + isInstance = isInstance && "assetId" in value; + isInstance = isInstance && "success" in value; + + return isInstance; +} + +export function AssetIdsResponseDtoFromJSON(json: any): AssetIdsResponseDto { + return AssetIdsResponseDtoFromJSONTyped(json, false); +} + +export function AssetIdsResponseDtoFromJSONTyped(json: any, ignoreDiscriminator: boolean): AssetIdsResponseDto { + if ((json === undefined) || (json === null)) { + return json; + } + return { + + 'assetId': json['assetId'], + 'error': !exists(json, 'error') ? undefined : json['error'], + 'success': json['success'], + }; +} + +export function AssetIdsResponseDtoToJSON(value?: AssetIdsResponseDto | null): any { + if (value === undefined) { + return undefined; + } + if (value === null) { + return null; + } + return { + + 'assetId': value.assetId, + 'error': value.error, + 'success': value.success, + }; +} + diff --git a/open-api/typescript-sdk/fetch-client/models/AssetJobName.ts b/open-api/typescript-sdk/fetch-client/models/AssetJobName.ts new file mode 100644 index 0000000000..7653107ee9 --- /dev/null +++ b/open-api/typescript-sdk/fetch-client/models/AssetJobName.ts @@ -0,0 +1,39 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * Immich + * Immich API + * + * The version of the OpenAPI document: 1.94.1 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + + +/** + * + * @export + */ +export const AssetJobName = { + RegenerateThumbnail: 'regenerate-thumbnail', + RefreshMetadata: 'refresh-metadata', + TranscodeVideo: 'transcode-video' +} as const; +export type AssetJobName = typeof AssetJobName[keyof typeof AssetJobName]; + + +export function AssetJobNameFromJSON(json: any): AssetJobName { + return AssetJobNameFromJSONTyped(json, false); +} + +export function AssetJobNameFromJSONTyped(json: any, ignoreDiscriminator: boolean): AssetJobName { + return json as AssetJobName; +} + +export function AssetJobNameToJSON(value?: AssetJobName | null): any { + return value as any; +} + diff --git a/open-api/typescript-sdk/fetch-client/models/AssetJobsDto.ts b/open-api/typescript-sdk/fetch-client/models/AssetJobsDto.ts new file mode 100644 index 0000000000..0a5edbf18a --- /dev/null +++ b/open-api/typescript-sdk/fetch-client/models/AssetJobsDto.ts @@ -0,0 +1,82 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * Immich + * Immich API + * + * The version of the OpenAPI document: 1.94.1 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + +import { exists, mapValues } from '../runtime'; +import type { AssetJobName } from './AssetJobName'; +import { + AssetJobNameFromJSON, + AssetJobNameFromJSONTyped, + AssetJobNameToJSON, +} from './AssetJobName'; + +/** + * + * @export + * @interface AssetJobsDto + */ +export interface AssetJobsDto { + /** + * + * @type {Array} + * @memberof AssetJobsDto + */ + assetIds: Array; + /** + * + * @type {AssetJobName} + * @memberof AssetJobsDto + */ + name: AssetJobName; +} + +/** + * Check if a given object implements the AssetJobsDto interface. + */ +export function instanceOfAssetJobsDto(value: object): boolean { + let isInstance = true; + isInstance = isInstance && "assetIds" in value; + isInstance = isInstance && "name" in value; + + return isInstance; +} + +export function AssetJobsDtoFromJSON(json: any): AssetJobsDto { + return AssetJobsDtoFromJSONTyped(json, false); +} + +export function AssetJobsDtoFromJSONTyped(json: any, ignoreDiscriminator: boolean): AssetJobsDto { + if ((json === undefined) || (json === null)) { + return json; + } + return { + + 'assetIds': json['assetIds'], + 'name': AssetJobNameFromJSON(json['name']), + }; +} + +export function AssetJobsDtoToJSON(value?: AssetJobsDto | null): any { + if (value === undefined) { + return undefined; + } + if (value === null) { + return null; + } + return { + + 'assetIds': value.assetIds, + 'name': AssetJobNameToJSON(value.name), + }; +} + diff --git a/open-api/typescript-sdk/fetch-client/models/AssetOrder.ts b/open-api/typescript-sdk/fetch-client/models/AssetOrder.ts new file mode 100644 index 0000000000..6d11fef5d4 --- /dev/null +++ b/open-api/typescript-sdk/fetch-client/models/AssetOrder.ts @@ -0,0 +1,38 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * Immich + * Immich API + * + * The version of the OpenAPI document: 1.94.1 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + + +/** + * + * @export + */ +export const AssetOrder = { + Asc: 'asc', + Desc: 'desc' +} as const; +export type AssetOrder = typeof AssetOrder[keyof typeof AssetOrder]; + + +export function AssetOrderFromJSON(json: any): AssetOrder { + return AssetOrderFromJSONTyped(json, false); +} + +export function AssetOrderFromJSONTyped(json: any, ignoreDiscriminator: boolean): AssetOrder { + return json as AssetOrder; +} + +export function AssetOrderToJSON(value?: AssetOrder | null): any { + return value as any; +} + diff --git a/open-api/typescript-sdk/fetch-client/models/AssetResponseDto.ts b/open-api/typescript-sdk/fetch-client/models/AssetResponseDto.ts new file mode 100644 index 0000000000..16193beb50 --- /dev/null +++ b/open-api/typescript-sdk/fetch-client/models/AssetResponseDto.ts @@ -0,0 +1,374 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * Immich + * Immich API + * + * The version of the OpenAPI document: 1.94.1 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + +import { exists, mapValues } from '../runtime'; +import type { AssetTypeEnum } from './AssetTypeEnum'; +import { + AssetTypeEnumFromJSON, + AssetTypeEnumFromJSONTyped, + AssetTypeEnumToJSON, +} from './AssetTypeEnum'; +import type { ExifResponseDto } from './ExifResponseDto'; +import { + ExifResponseDtoFromJSON, + ExifResponseDtoFromJSONTyped, + ExifResponseDtoToJSON, +} from './ExifResponseDto'; +import type { PersonWithFacesResponseDto } from './PersonWithFacesResponseDto'; +import { + PersonWithFacesResponseDtoFromJSON, + PersonWithFacesResponseDtoFromJSONTyped, + PersonWithFacesResponseDtoToJSON, +} from './PersonWithFacesResponseDto'; +import type { SmartInfoResponseDto } from './SmartInfoResponseDto'; +import { + SmartInfoResponseDtoFromJSON, + SmartInfoResponseDtoFromJSONTyped, + SmartInfoResponseDtoToJSON, +} from './SmartInfoResponseDto'; +import type { TagResponseDto } from './TagResponseDto'; +import { + TagResponseDtoFromJSON, + TagResponseDtoFromJSONTyped, + TagResponseDtoToJSON, +} from './TagResponseDto'; +import type { UserResponseDto } from './UserResponseDto'; +import { + UserResponseDtoFromJSON, + UserResponseDtoFromJSONTyped, + UserResponseDtoToJSON, +} from './UserResponseDto'; + +/** + * + * @export + * @interface AssetResponseDto + */ +export interface AssetResponseDto { + /** + * base64 encoded sha1 hash + * @type {string} + * @memberof AssetResponseDto + */ + checksum: string; + /** + * + * @type {string} + * @memberof AssetResponseDto + */ + deviceAssetId: string; + /** + * + * @type {string} + * @memberof AssetResponseDto + */ + deviceId: string; + /** + * + * @type {string} + * @memberof AssetResponseDto + */ + duration: string; + /** + * + * @type {ExifResponseDto} + * @memberof AssetResponseDto + */ + exifInfo?: ExifResponseDto; + /** + * + * @type {Date} + * @memberof AssetResponseDto + */ + fileCreatedAt: Date; + /** + * + * @type {Date} + * @memberof AssetResponseDto + */ + fileModifiedAt: Date; + /** + * + * @type {boolean} + * @memberof AssetResponseDto + */ + hasMetadata: boolean; + /** + * + * @type {string} + * @memberof AssetResponseDto + */ + id: string; + /** + * + * @type {boolean} + * @memberof AssetResponseDto + */ + isArchived: boolean; + /** + * + * @type {boolean} + * @memberof AssetResponseDto + */ + isExternal: boolean; + /** + * + * @type {boolean} + * @memberof AssetResponseDto + */ + isFavorite: boolean; + /** + * + * @type {boolean} + * @memberof AssetResponseDto + */ + isOffline: boolean; + /** + * + * @type {boolean} + * @memberof AssetResponseDto + */ + isReadOnly: boolean; + /** + * + * @type {boolean} + * @memberof AssetResponseDto + */ + isTrashed: boolean; + /** + * + * @type {string} + * @memberof AssetResponseDto + */ + libraryId: string; + /** + * + * @type {string} + * @memberof AssetResponseDto + */ + livePhotoVideoId?: string | null; + /** + * + * @type {Date} + * @memberof AssetResponseDto + */ + localDateTime: Date; + /** + * + * @type {string} + * @memberof AssetResponseDto + */ + originalFileName: string; + /** + * + * @type {string} + * @memberof AssetResponseDto + */ + originalPath: string; + /** + * + * @type {UserResponseDto} + * @memberof AssetResponseDto + */ + owner?: UserResponseDto; + /** + * + * @type {string} + * @memberof AssetResponseDto + */ + ownerId: string; + /** + * + * @type {Array} + * @memberof AssetResponseDto + */ + people?: Array; + /** + * + * @type {boolean} + * @memberof AssetResponseDto + */ + resized: boolean; + /** + * + * @type {SmartInfoResponseDto} + * @memberof AssetResponseDto + */ + smartInfo?: SmartInfoResponseDto; + /** + * + * @type {Array} + * @memberof AssetResponseDto + */ + stack?: Array; + /** + * + * @type {number} + * @memberof AssetResponseDto + */ + stackCount: number | null; + /** + * + * @type {string} + * @memberof AssetResponseDto + */ + stackParentId?: string | null; + /** + * + * @type {Array} + * @memberof AssetResponseDto + */ + tags?: Array; + /** + * + * @type {string} + * @memberof AssetResponseDto + */ + thumbhash: string | null; + /** + * + * @type {AssetTypeEnum} + * @memberof AssetResponseDto + */ + type: AssetTypeEnum; + /** + * + * @type {Date} + * @memberof AssetResponseDto + */ + updatedAt: Date; +} + +/** + * Check if a given object implements the AssetResponseDto interface. + */ +export function instanceOfAssetResponseDto(value: object): boolean { + let isInstance = true; + isInstance = isInstance && "checksum" in value; + isInstance = isInstance && "deviceAssetId" in value; + isInstance = isInstance && "deviceId" in value; + isInstance = isInstance && "duration" in value; + isInstance = isInstance && "fileCreatedAt" in value; + isInstance = isInstance && "fileModifiedAt" in value; + isInstance = isInstance && "hasMetadata" in value; + isInstance = isInstance && "id" in value; + isInstance = isInstance && "isArchived" in value; + isInstance = isInstance && "isExternal" in value; + isInstance = isInstance && "isFavorite" in value; + isInstance = isInstance && "isOffline" in value; + isInstance = isInstance && "isReadOnly" in value; + isInstance = isInstance && "isTrashed" in value; + isInstance = isInstance && "libraryId" in value; + isInstance = isInstance && "localDateTime" in value; + isInstance = isInstance && "originalFileName" in value; + isInstance = isInstance && "originalPath" in value; + isInstance = isInstance && "ownerId" in value; + isInstance = isInstance && "resized" in value; + isInstance = isInstance && "stackCount" in value; + isInstance = isInstance && "thumbhash" in value; + isInstance = isInstance && "type" in value; + isInstance = isInstance && "updatedAt" in value; + + return isInstance; +} + +export function AssetResponseDtoFromJSON(json: any): AssetResponseDto { + return AssetResponseDtoFromJSONTyped(json, false); +} + +export function AssetResponseDtoFromJSONTyped(json: any, ignoreDiscriminator: boolean): AssetResponseDto { + if ((json === undefined) || (json === null)) { + return json; + } + return { + + 'checksum': json['checksum'], + 'deviceAssetId': json['deviceAssetId'], + 'deviceId': json['deviceId'], + 'duration': json['duration'], + 'exifInfo': !exists(json, 'exifInfo') ? undefined : ExifResponseDtoFromJSON(json['exifInfo']), + 'fileCreatedAt': (new Date(json['fileCreatedAt'])), + 'fileModifiedAt': (new Date(json['fileModifiedAt'])), + 'hasMetadata': json['hasMetadata'], + 'id': json['id'], + 'isArchived': json['isArchived'], + 'isExternal': json['isExternal'], + 'isFavorite': json['isFavorite'], + 'isOffline': json['isOffline'], + 'isReadOnly': json['isReadOnly'], + 'isTrashed': json['isTrashed'], + 'libraryId': json['libraryId'], + 'livePhotoVideoId': !exists(json, 'livePhotoVideoId') ? undefined : json['livePhotoVideoId'], + 'localDateTime': (new Date(json['localDateTime'])), + 'originalFileName': json['originalFileName'], + 'originalPath': json['originalPath'], + 'owner': !exists(json, 'owner') ? undefined : UserResponseDtoFromJSON(json['owner']), + 'ownerId': json['ownerId'], + 'people': !exists(json, 'people') ? undefined : ((json['people'] as Array).map(PersonWithFacesResponseDtoFromJSON)), + 'resized': json['resized'], + 'smartInfo': !exists(json, 'smartInfo') ? undefined : SmartInfoResponseDtoFromJSON(json['smartInfo']), + 'stack': !exists(json, 'stack') ? undefined : ((json['stack'] as Array).map(AssetResponseDtoFromJSON)), + 'stackCount': json['stackCount'], + 'stackParentId': !exists(json, 'stackParentId') ? undefined : json['stackParentId'], + 'tags': !exists(json, 'tags') ? undefined : ((json['tags'] as Array).map(TagResponseDtoFromJSON)), + 'thumbhash': json['thumbhash'], + 'type': AssetTypeEnumFromJSON(json['type']), + 'updatedAt': (new Date(json['updatedAt'])), + }; +} + +export function AssetResponseDtoToJSON(value?: AssetResponseDto | null): any { + if (value === undefined) { + return undefined; + } + if (value === null) { + return null; + } + return { + + 'checksum': value.checksum, + 'deviceAssetId': value.deviceAssetId, + 'deviceId': value.deviceId, + 'duration': value.duration, + 'exifInfo': ExifResponseDtoToJSON(value.exifInfo), + 'fileCreatedAt': (value.fileCreatedAt.toISOString()), + 'fileModifiedAt': (value.fileModifiedAt.toISOString()), + 'hasMetadata': value.hasMetadata, + 'id': value.id, + 'isArchived': value.isArchived, + 'isExternal': value.isExternal, + 'isFavorite': value.isFavorite, + 'isOffline': value.isOffline, + 'isReadOnly': value.isReadOnly, + 'isTrashed': value.isTrashed, + 'libraryId': value.libraryId, + 'livePhotoVideoId': value.livePhotoVideoId, + 'localDateTime': (value.localDateTime.toISOString()), + 'originalFileName': value.originalFileName, + 'originalPath': value.originalPath, + 'owner': UserResponseDtoToJSON(value.owner), + 'ownerId': value.ownerId, + 'people': value.people === undefined ? undefined : ((value.people as Array).map(PersonWithFacesResponseDtoToJSON)), + 'resized': value.resized, + 'smartInfo': SmartInfoResponseDtoToJSON(value.smartInfo), + 'stack': value.stack === undefined ? undefined : ((value.stack as Array).map(AssetResponseDtoToJSON)), + 'stackCount': value.stackCount, + 'stackParentId': value.stackParentId, + 'tags': value.tags === undefined ? undefined : ((value.tags as Array).map(TagResponseDtoToJSON)), + 'thumbhash': value.thumbhash, + 'type': AssetTypeEnumToJSON(value.type), + 'updatedAt': (value.updatedAt.toISOString()), + }; +} + diff --git a/open-api/typescript-sdk/fetch-client/models/AssetStatsResponseDto.ts b/open-api/typescript-sdk/fetch-client/models/AssetStatsResponseDto.ts new file mode 100644 index 0000000000..4907cb4ca9 --- /dev/null +++ b/open-api/typescript-sdk/fetch-client/models/AssetStatsResponseDto.ts @@ -0,0 +1,84 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * Immich + * Immich API + * + * The version of the OpenAPI document: 1.94.1 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + +import { exists, mapValues } from '../runtime'; +/** + * + * @export + * @interface AssetStatsResponseDto + */ +export interface AssetStatsResponseDto { + /** + * + * @type {number} + * @memberof AssetStatsResponseDto + */ + images: number; + /** + * + * @type {number} + * @memberof AssetStatsResponseDto + */ + total: number; + /** + * + * @type {number} + * @memberof AssetStatsResponseDto + */ + videos: number; +} + +/** + * Check if a given object implements the AssetStatsResponseDto interface. + */ +export function instanceOfAssetStatsResponseDto(value: object): boolean { + let isInstance = true; + isInstance = isInstance && "images" in value; + isInstance = isInstance && "total" in value; + isInstance = isInstance && "videos" in value; + + return isInstance; +} + +export function AssetStatsResponseDtoFromJSON(json: any): AssetStatsResponseDto { + return AssetStatsResponseDtoFromJSONTyped(json, false); +} + +export function AssetStatsResponseDtoFromJSONTyped(json: any, ignoreDiscriminator: boolean): AssetStatsResponseDto { + if ((json === undefined) || (json === null)) { + return json; + } + return { + + 'images': json['images'], + 'total': json['total'], + 'videos': json['videos'], + }; +} + +export function AssetStatsResponseDtoToJSON(value?: AssetStatsResponseDto | null): any { + if (value === undefined) { + return undefined; + } + if (value === null) { + return null; + } + return { + + 'images': value.images, + 'total': value.total, + 'videos': value.videos, + }; +} + diff --git a/open-api/typescript-sdk/fetch-client/models/AssetTypeEnum.ts b/open-api/typescript-sdk/fetch-client/models/AssetTypeEnum.ts new file mode 100644 index 0000000000..cfbf259855 --- /dev/null +++ b/open-api/typescript-sdk/fetch-client/models/AssetTypeEnum.ts @@ -0,0 +1,40 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * Immich + * Immich API + * + * The version of the OpenAPI document: 1.94.1 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + + +/** + * + * @export + */ +export const AssetTypeEnum = { + Image: 'IMAGE', + Video: 'VIDEO', + Audio: 'AUDIO', + Other: 'OTHER' +} as const; +export type AssetTypeEnum = typeof AssetTypeEnum[keyof typeof AssetTypeEnum]; + + +export function AssetTypeEnumFromJSON(json: any): AssetTypeEnum { + return AssetTypeEnumFromJSONTyped(json, false); +} + +export function AssetTypeEnumFromJSONTyped(json: any, ignoreDiscriminator: boolean): AssetTypeEnum { + return json as AssetTypeEnum; +} + +export function AssetTypeEnumToJSON(value?: AssetTypeEnum | null): any { + return value as any; +} + diff --git a/open-api/typescript-sdk/fetch-client/models/AudioCodec.ts b/open-api/typescript-sdk/fetch-client/models/AudioCodec.ts new file mode 100644 index 0000000000..586e8f1591 --- /dev/null +++ b/open-api/typescript-sdk/fetch-client/models/AudioCodec.ts @@ -0,0 +1,39 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * Immich + * Immich API + * + * The version of the OpenAPI document: 1.94.1 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + + +/** + * + * @export + */ +export const AudioCodec = { + Mp3: 'mp3', + Aac: 'aac', + Libopus: 'libopus' +} as const; +export type AudioCodec = typeof AudioCodec[keyof typeof AudioCodec]; + + +export function AudioCodecFromJSON(json: any): AudioCodec { + return AudioCodecFromJSONTyped(json, false); +} + +export function AudioCodecFromJSONTyped(json: any, ignoreDiscriminator: boolean): AudioCodec { + return json as AudioCodec; +} + +export function AudioCodecToJSON(value?: AudioCodec | null): any { + return value as any; +} + diff --git a/open-api/typescript-sdk/fetch-client/models/AuditDeletesResponseDto.ts b/open-api/typescript-sdk/fetch-client/models/AuditDeletesResponseDto.ts new file mode 100644 index 0000000000..0d6b6e167b --- /dev/null +++ b/open-api/typescript-sdk/fetch-client/models/AuditDeletesResponseDto.ts @@ -0,0 +1,75 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * Immich + * Immich API + * + * The version of the OpenAPI document: 1.94.1 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + +import { exists, mapValues } from '../runtime'; +/** + * + * @export + * @interface AuditDeletesResponseDto + */ +export interface AuditDeletesResponseDto { + /** + * + * @type {Array} + * @memberof AuditDeletesResponseDto + */ + ids: Array; + /** + * + * @type {boolean} + * @memberof AuditDeletesResponseDto + */ + needsFullSync: boolean; +} + +/** + * Check if a given object implements the AuditDeletesResponseDto interface. + */ +export function instanceOfAuditDeletesResponseDto(value: object): boolean { + let isInstance = true; + isInstance = isInstance && "ids" in value; + isInstance = isInstance && "needsFullSync" in value; + + return isInstance; +} + +export function AuditDeletesResponseDtoFromJSON(json: any): AuditDeletesResponseDto { + return AuditDeletesResponseDtoFromJSONTyped(json, false); +} + +export function AuditDeletesResponseDtoFromJSONTyped(json: any, ignoreDiscriminator: boolean): AuditDeletesResponseDto { + if ((json === undefined) || (json === null)) { + return json; + } + return { + + 'ids': json['ids'], + 'needsFullSync': json['needsFullSync'], + }; +} + +export function AuditDeletesResponseDtoToJSON(value?: AuditDeletesResponseDto | null): any { + if (value === undefined) { + return undefined; + } + if (value === null) { + return null; + } + return { + + 'ids': value.ids, + 'needsFullSync': value.needsFullSync, + }; +} + diff --git a/open-api/typescript-sdk/fetch-client/models/AuthDeviceResponseDto.ts b/open-api/typescript-sdk/fetch-client/models/AuthDeviceResponseDto.ts new file mode 100644 index 0000000000..252180dd71 --- /dev/null +++ b/open-api/typescript-sdk/fetch-client/models/AuthDeviceResponseDto.ts @@ -0,0 +1,111 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * Immich + * Immich API + * + * The version of the OpenAPI document: 1.94.1 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + +import { exists, mapValues } from '../runtime'; +/** + * + * @export + * @interface AuthDeviceResponseDto + */ +export interface AuthDeviceResponseDto { + /** + * + * @type {string} + * @memberof AuthDeviceResponseDto + */ + createdAt: string; + /** + * + * @type {boolean} + * @memberof AuthDeviceResponseDto + */ + current: boolean; + /** + * + * @type {string} + * @memberof AuthDeviceResponseDto + */ + deviceOS: string; + /** + * + * @type {string} + * @memberof AuthDeviceResponseDto + */ + deviceType: string; + /** + * + * @type {string} + * @memberof AuthDeviceResponseDto + */ + id: string; + /** + * + * @type {string} + * @memberof AuthDeviceResponseDto + */ + updatedAt: string; +} + +/** + * Check if a given object implements the AuthDeviceResponseDto interface. + */ +export function instanceOfAuthDeviceResponseDto(value: object): boolean { + let isInstance = true; + isInstance = isInstance && "createdAt" in value; + isInstance = isInstance && "current" in value; + isInstance = isInstance && "deviceOS" in value; + isInstance = isInstance && "deviceType" in value; + isInstance = isInstance && "id" in value; + isInstance = isInstance && "updatedAt" in value; + + return isInstance; +} + +export function AuthDeviceResponseDtoFromJSON(json: any): AuthDeviceResponseDto { + return AuthDeviceResponseDtoFromJSONTyped(json, false); +} + +export function AuthDeviceResponseDtoFromJSONTyped(json: any, ignoreDiscriminator: boolean): AuthDeviceResponseDto { + if ((json === undefined) || (json === null)) { + return json; + } + return { + + 'createdAt': json['createdAt'], + 'current': json['current'], + 'deviceOS': json['deviceOS'], + 'deviceType': json['deviceType'], + 'id': json['id'], + 'updatedAt': json['updatedAt'], + }; +} + +export function AuthDeviceResponseDtoToJSON(value?: AuthDeviceResponseDto | null): any { + if (value === undefined) { + return undefined; + } + if (value === null) { + return null; + } + return { + + 'createdAt': value.createdAt, + 'current': value.current, + 'deviceOS': value.deviceOS, + 'deviceType': value.deviceType, + 'id': value.id, + 'updatedAt': value.updatedAt, + }; +} + diff --git a/open-api/typescript-sdk/fetch-client/models/BulkIdResponseDto.ts b/open-api/typescript-sdk/fetch-client/models/BulkIdResponseDto.ts new file mode 100644 index 0000000000..7c0fb036f8 --- /dev/null +++ b/open-api/typescript-sdk/fetch-client/models/BulkIdResponseDto.ts @@ -0,0 +1,96 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * Immich + * Immich API + * + * The version of the OpenAPI document: 1.94.1 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + +import { exists, mapValues } from '../runtime'; +/** + * + * @export + * @interface BulkIdResponseDto + */ +export interface BulkIdResponseDto { + /** + * + * @type {string} + * @memberof BulkIdResponseDto + */ + error?: BulkIdResponseDtoErrorEnum; + /** + * + * @type {string} + * @memberof BulkIdResponseDto + */ + id: string; + /** + * + * @type {boolean} + * @memberof BulkIdResponseDto + */ + success: boolean; +} + + +/** + * @export + */ +export const BulkIdResponseDtoErrorEnum = { + Duplicate: 'duplicate', + NoPermission: 'no_permission', + NotFound: 'not_found', + Unknown: 'unknown' +} as const; +export type BulkIdResponseDtoErrorEnum = typeof BulkIdResponseDtoErrorEnum[keyof typeof BulkIdResponseDtoErrorEnum]; + + +/** + * Check if a given object implements the BulkIdResponseDto interface. + */ +export function instanceOfBulkIdResponseDto(value: object): boolean { + let isInstance = true; + isInstance = isInstance && "id" in value; + isInstance = isInstance && "success" in value; + + return isInstance; +} + +export function BulkIdResponseDtoFromJSON(json: any): BulkIdResponseDto { + return BulkIdResponseDtoFromJSONTyped(json, false); +} + +export function BulkIdResponseDtoFromJSONTyped(json: any, ignoreDiscriminator: boolean): BulkIdResponseDto { + if ((json === undefined) || (json === null)) { + return json; + } + return { + + 'error': !exists(json, 'error') ? undefined : json['error'], + 'id': json['id'], + 'success': json['success'], + }; +} + +export function BulkIdResponseDtoToJSON(value?: BulkIdResponseDto | null): any { + if (value === undefined) { + return undefined; + } + if (value === null) { + return null; + } + return { + + 'error': value.error, + 'id': value.id, + 'success': value.success, + }; +} + diff --git a/open-api/typescript-sdk/fetch-client/models/BulkIdsDto.ts b/open-api/typescript-sdk/fetch-client/models/BulkIdsDto.ts new file mode 100644 index 0000000000..3aae1f4323 --- /dev/null +++ b/open-api/typescript-sdk/fetch-client/models/BulkIdsDto.ts @@ -0,0 +1,66 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * Immich + * Immich API + * + * The version of the OpenAPI document: 1.94.1 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + +import { exists, mapValues } from '../runtime'; +/** + * + * @export + * @interface BulkIdsDto + */ +export interface BulkIdsDto { + /** + * + * @type {Array} + * @memberof BulkIdsDto + */ + ids: Array; +} + +/** + * Check if a given object implements the BulkIdsDto interface. + */ +export function instanceOfBulkIdsDto(value: object): boolean { + let isInstance = true; + isInstance = isInstance && "ids" in value; + + return isInstance; +} + +export function BulkIdsDtoFromJSON(json: any): BulkIdsDto { + return BulkIdsDtoFromJSONTyped(json, false); +} + +export function BulkIdsDtoFromJSONTyped(json: any, ignoreDiscriminator: boolean): BulkIdsDto { + if ((json === undefined) || (json === null)) { + return json; + } + return { + + 'ids': json['ids'], + }; +} + +export function BulkIdsDtoToJSON(value?: BulkIdsDto | null): any { + if (value === undefined) { + return undefined; + } + if (value === null) { + return null; + } + return { + + 'ids': value.ids, + }; +} + diff --git a/open-api/typescript-sdk/fetch-client/models/CLIPConfig.ts b/open-api/typescript-sdk/fetch-client/models/CLIPConfig.ts new file mode 100644 index 0000000000..30175e3365 --- /dev/null +++ b/open-api/typescript-sdk/fetch-client/models/CLIPConfig.ts @@ -0,0 +1,104 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * Immich + * Immich API + * + * The version of the OpenAPI document: 1.94.1 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + +import { exists, mapValues } from '../runtime'; +import type { CLIPMode } from './CLIPMode'; +import { + CLIPModeFromJSON, + CLIPModeFromJSONTyped, + CLIPModeToJSON, +} from './CLIPMode'; +import type { ModelType } from './ModelType'; +import { + ModelTypeFromJSON, + ModelTypeFromJSONTyped, + ModelTypeToJSON, +} from './ModelType'; + +/** + * + * @export + * @interface CLIPConfig + */ +export interface CLIPConfig { + /** + * + * @type {boolean} + * @memberof CLIPConfig + */ + enabled: boolean; + /** + * + * @type {CLIPMode} + * @memberof CLIPConfig + */ + mode?: CLIPMode; + /** + * + * @type {string} + * @memberof CLIPConfig + */ + modelName: string; + /** + * + * @type {ModelType} + * @memberof CLIPConfig + */ + modelType?: ModelType; +} + +/** + * Check if a given object implements the CLIPConfig interface. + */ +export function instanceOfCLIPConfig(value: object): boolean { + let isInstance = true; + isInstance = isInstance && "enabled" in value; + isInstance = isInstance && "modelName" in value; + + return isInstance; +} + +export function CLIPConfigFromJSON(json: any): CLIPConfig { + return CLIPConfigFromJSONTyped(json, false); +} + +export function CLIPConfigFromJSONTyped(json: any, ignoreDiscriminator: boolean): CLIPConfig { + if ((json === undefined) || (json === null)) { + return json; + } + return { + + 'enabled': json['enabled'], + 'mode': !exists(json, 'mode') ? undefined : CLIPModeFromJSON(json['mode']), + 'modelName': json['modelName'], + 'modelType': !exists(json, 'modelType') ? undefined : ModelTypeFromJSON(json['modelType']), + }; +} + +export function CLIPConfigToJSON(value?: CLIPConfig | null): any { + if (value === undefined) { + return undefined; + } + if (value === null) { + return null; + } + return { + + 'enabled': value.enabled, + 'mode': CLIPModeToJSON(value.mode), + 'modelName': value.modelName, + 'modelType': ModelTypeToJSON(value.modelType), + }; +} + diff --git a/open-api/typescript-sdk/fetch-client/models/CLIPMode.ts b/open-api/typescript-sdk/fetch-client/models/CLIPMode.ts new file mode 100644 index 0000000000..e47c82235f --- /dev/null +++ b/open-api/typescript-sdk/fetch-client/models/CLIPMode.ts @@ -0,0 +1,38 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * Immich + * Immich API + * + * The version of the OpenAPI document: 1.94.1 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + + +/** + * + * @export + */ +export const CLIPMode = { + Vision: 'vision', + Text: 'text' +} as const; +export type CLIPMode = typeof CLIPMode[keyof typeof CLIPMode]; + + +export function CLIPModeFromJSON(json: any): CLIPMode { + return CLIPModeFromJSONTyped(json, false); +} + +export function CLIPModeFromJSONTyped(json: any, ignoreDiscriminator: boolean): CLIPMode { + return json as CLIPMode; +} + +export function CLIPModeToJSON(value?: CLIPMode | null): any { + return value as any; +} + diff --git a/open-api/typescript-sdk/fetch-client/models/CQMode.ts b/open-api/typescript-sdk/fetch-client/models/CQMode.ts new file mode 100644 index 0000000000..d04202d767 --- /dev/null +++ b/open-api/typescript-sdk/fetch-client/models/CQMode.ts @@ -0,0 +1,39 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * Immich + * Immich API + * + * The version of the OpenAPI document: 1.94.1 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + + +/** + * + * @export + */ +export const CQMode = { + Auto: 'auto', + Cqp: 'cqp', + Icq: 'icq' +} as const; +export type CQMode = typeof CQMode[keyof typeof CQMode]; + + +export function CQModeFromJSON(json: any): CQMode { + return CQModeFromJSONTyped(json, false); +} + +export function CQModeFromJSONTyped(json: any, ignoreDiscriminator: boolean): CQMode { + return json as CQMode; +} + +export function CQModeToJSON(value?: CQMode | null): any { + return value as any; +} + diff --git a/open-api/typescript-sdk/fetch-client/models/ChangePasswordDto.ts b/open-api/typescript-sdk/fetch-client/models/ChangePasswordDto.ts new file mode 100644 index 0000000000..3ff18fa91a --- /dev/null +++ b/open-api/typescript-sdk/fetch-client/models/ChangePasswordDto.ts @@ -0,0 +1,75 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * Immich + * Immich API + * + * The version of the OpenAPI document: 1.94.1 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + +import { exists, mapValues } from '../runtime'; +/** + * + * @export + * @interface ChangePasswordDto + */ +export interface ChangePasswordDto { + /** + * + * @type {string} + * @memberof ChangePasswordDto + */ + newPassword: string; + /** + * + * @type {string} + * @memberof ChangePasswordDto + */ + password: string; +} + +/** + * Check if a given object implements the ChangePasswordDto interface. + */ +export function instanceOfChangePasswordDto(value: object): boolean { + let isInstance = true; + isInstance = isInstance && "newPassword" in value; + isInstance = isInstance && "password" in value; + + return isInstance; +} + +export function ChangePasswordDtoFromJSON(json: any): ChangePasswordDto { + return ChangePasswordDtoFromJSONTyped(json, false); +} + +export function ChangePasswordDtoFromJSONTyped(json: any, ignoreDiscriminator: boolean): ChangePasswordDto { + if ((json === undefined) || (json === null)) { + return json; + } + return { + + 'newPassword': json['newPassword'], + 'password': json['password'], + }; +} + +export function ChangePasswordDtoToJSON(value?: ChangePasswordDto | null): any { + if (value === undefined) { + return undefined; + } + if (value === null) { + return null; + } + return { + + 'newPassword': value.newPassword, + 'password': value.password, + }; +} + diff --git a/open-api/typescript-sdk/fetch-client/models/CheckExistingAssetsDto.ts b/open-api/typescript-sdk/fetch-client/models/CheckExistingAssetsDto.ts new file mode 100644 index 0000000000..8d137d9da9 --- /dev/null +++ b/open-api/typescript-sdk/fetch-client/models/CheckExistingAssetsDto.ts @@ -0,0 +1,75 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * Immich + * Immich API + * + * The version of the OpenAPI document: 1.94.1 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + +import { exists, mapValues } from '../runtime'; +/** + * + * @export + * @interface CheckExistingAssetsDto + */ +export interface CheckExistingAssetsDto { + /** + * + * @type {Array} + * @memberof CheckExistingAssetsDto + */ + deviceAssetIds: Array; + /** + * + * @type {string} + * @memberof CheckExistingAssetsDto + */ + deviceId: string; +} + +/** + * Check if a given object implements the CheckExistingAssetsDto interface. + */ +export function instanceOfCheckExistingAssetsDto(value: object): boolean { + let isInstance = true; + isInstance = isInstance && "deviceAssetIds" in value; + isInstance = isInstance && "deviceId" in value; + + return isInstance; +} + +export function CheckExistingAssetsDtoFromJSON(json: any): CheckExistingAssetsDto { + return CheckExistingAssetsDtoFromJSONTyped(json, false); +} + +export function CheckExistingAssetsDtoFromJSONTyped(json: any, ignoreDiscriminator: boolean): CheckExistingAssetsDto { + if ((json === undefined) || (json === null)) { + return json; + } + return { + + 'deviceAssetIds': json['deviceAssetIds'], + 'deviceId': json['deviceId'], + }; +} + +export function CheckExistingAssetsDtoToJSON(value?: CheckExistingAssetsDto | null): any { + if (value === undefined) { + return undefined; + } + if (value === null) { + return null; + } + return { + + 'deviceAssetIds': value.deviceAssetIds, + 'deviceId': value.deviceId, + }; +} + diff --git a/open-api/typescript-sdk/fetch-client/models/CheckExistingAssetsResponseDto.ts b/open-api/typescript-sdk/fetch-client/models/CheckExistingAssetsResponseDto.ts new file mode 100644 index 0000000000..54bac21ca1 --- /dev/null +++ b/open-api/typescript-sdk/fetch-client/models/CheckExistingAssetsResponseDto.ts @@ -0,0 +1,66 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * Immich + * Immich API + * + * The version of the OpenAPI document: 1.94.1 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + +import { exists, mapValues } from '../runtime'; +/** + * + * @export + * @interface CheckExistingAssetsResponseDto + */ +export interface CheckExistingAssetsResponseDto { + /** + * + * @type {Array} + * @memberof CheckExistingAssetsResponseDto + */ + existingIds: Array; +} + +/** + * Check if a given object implements the CheckExistingAssetsResponseDto interface. + */ +export function instanceOfCheckExistingAssetsResponseDto(value: object): boolean { + let isInstance = true; + isInstance = isInstance && "existingIds" in value; + + return isInstance; +} + +export function CheckExistingAssetsResponseDtoFromJSON(json: any): CheckExistingAssetsResponseDto { + return CheckExistingAssetsResponseDtoFromJSONTyped(json, false); +} + +export function CheckExistingAssetsResponseDtoFromJSONTyped(json: any, ignoreDiscriminator: boolean): CheckExistingAssetsResponseDto { + if ((json === undefined) || (json === null)) { + return json; + } + return { + + 'existingIds': json['existingIds'], + }; +} + +export function CheckExistingAssetsResponseDtoToJSON(value?: CheckExistingAssetsResponseDto | null): any { + if (value === undefined) { + return undefined; + } + if (value === null) { + return null; + } + return { + + 'existingIds': value.existingIds, + }; +} + diff --git a/open-api/typescript-sdk/fetch-client/models/Colorspace.ts b/open-api/typescript-sdk/fetch-client/models/Colorspace.ts new file mode 100644 index 0000000000..e10cde234e --- /dev/null +++ b/open-api/typescript-sdk/fetch-client/models/Colorspace.ts @@ -0,0 +1,38 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * Immich + * Immich API + * + * The version of the OpenAPI document: 1.94.1 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + + +/** + * + * @export + */ +export const Colorspace = { + Srgb: 'srgb', + P3: 'p3' +} as const; +export type Colorspace = typeof Colorspace[keyof typeof Colorspace]; + + +export function ColorspaceFromJSON(json: any): Colorspace { + return ColorspaceFromJSONTyped(json, false); +} + +export function ColorspaceFromJSONTyped(json: any, ignoreDiscriminator: boolean): Colorspace { + return json as Colorspace; +} + +export function ColorspaceToJSON(value?: Colorspace | null): any { + return value as any; +} + diff --git a/open-api/typescript-sdk/fetch-client/models/CreateAlbumDto.ts b/open-api/typescript-sdk/fetch-client/models/CreateAlbumDto.ts new file mode 100644 index 0000000000..d3f3c9f20e --- /dev/null +++ b/open-api/typescript-sdk/fetch-client/models/CreateAlbumDto.ts @@ -0,0 +1,90 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * Immich + * Immich API + * + * The version of the OpenAPI document: 1.94.1 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + +import { exists, mapValues } from '../runtime'; +/** + * + * @export + * @interface CreateAlbumDto + */ +export interface CreateAlbumDto { + /** + * + * @type {string} + * @memberof CreateAlbumDto + */ + albumName: string; + /** + * + * @type {Array} + * @memberof CreateAlbumDto + */ + assetIds?: Array; + /** + * + * @type {string} + * @memberof CreateAlbumDto + */ + description?: string; + /** + * + * @type {Array} + * @memberof CreateAlbumDto + */ + sharedWithUserIds?: Array; +} + +/** + * Check if a given object implements the CreateAlbumDto interface. + */ +export function instanceOfCreateAlbumDto(value: object): boolean { + let isInstance = true; + isInstance = isInstance && "albumName" in value; + + return isInstance; +} + +export function CreateAlbumDtoFromJSON(json: any): CreateAlbumDto { + return CreateAlbumDtoFromJSONTyped(json, false); +} + +export function CreateAlbumDtoFromJSONTyped(json: any, ignoreDiscriminator: boolean): CreateAlbumDto { + if ((json === undefined) || (json === null)) { + return json; + } + return { + + 'albumName': json['albumName'], + 'assetIds': !exists(json, 'assetIds') ? undefined : json['assetIds'], + 'description': !exists(json, 'description') ? undefined : json['description'], + 'sharedWithUserIds': !exists(json, 'sharedWithUserIds') ? undefined : json['sharedWithUserIds'], + }; +} + +export function CreateAlbumDtoToJSON(value?: CreateAlbumDto | null): any { + if (value === undefined) { + return undefined; + } + if (value === null) { + return null; + } + return { + + 'albumName': value.albumName, + 'assetIds': value.assetIds, + 'description': value.description, + 'sharedWithUserIds': value.sharedWithUserIds, + }; +} + diff --git a/open-api/typescript-sdk/fetch-client/models/CreateLibraryDto.ts b/open-api/typescript-sdk/fetch-client/models/CreateLibraryDto.ts new file mode 100644 index 0000000000..ef75f32fa8 --- /dev/null +++ b/open-api/typescript-sdk/fetch-client/models/CreateLibraryDto.ts @@ -0,0 +1,113 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * Immich + * Immich API + * + * The version of the OpenAPI document: 1.94.1 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + +import { exists, mapValues } from '../runtime'; +import type { LibraryType } from './LibraryType'; +import { + LibraryTypeFromJSON, + LibraryTypeFromJSONTyped, + LibraryTypeToJSON, +} from './LibraryType'; + +/** + * + * @export + * @interface CreateLibraryDto + */ +export interface CreateLibraryDto { + /** + * + * @type {Array} + * @memberof CreateLibraryDto + */ + exclusionPatterns?: Array; + /** + * + * @type {Array} + * @memberof CreateLibraryDto + */ + importPaths?: Array; + /** + * + * @type {boolean} + * @memberof CreateLibraryDto + */ + isVisible?: boolean; + /** + * + * @type {boolean} + * @memberof CreateLibraryDto + */ + isWatched?: boolean; + /** + * + * @type {string} + * @memberof CreateLibraryDto + */ + name?: string; + /** + * + * @type {LibraryType} + * @memberof CreateLibraryDto + */ + type: LibraryType; +} + +/** + * Check if a given object implements the CreateLibraryDto interface. + */ +export function instanceOfCreateLibraryDto(value: object): boolean { + let isInstance = true; + isInstance = isInstance && "type" in value; + + return isInstance; +} + +export function CreateLibraryDtoFromJSON(json: any): CreateLibraryDto { + return CreateLibraryDtoFromJSONTyped(json, false); +} + +export function CreateLibraryDtoFromJSONTyped(json: any, ignoreDiscriminator: boolean): CreateLibraryDto { + if ((json === undefined) || (json === null)) { + return json; + } + return { + + 'exclusionPatterns': !exists(json, 'exclusionPatterns') ? undefined : json['exclusionPatterns'], + 'importPaths': !exists(json, 'importPaths') ? undefined : json['importPaths'], + 'isVisible': !exists(json, 'isVisible') ? undefined : json['isVisible'], + 'isWatched': !exists(json, 'isWatched') ? undefined : json['isWatched'], + 'name': !exists(json, 'name') ? undefined : json['name'], + 'type': LibraryTypeFromJSON(json['type']), + }; +} + +export function CreateLibraryDtoToJSON(value?: CreateLibraryDto | null): any { + if (value === undefined) { + return undefined; + } + if (value === null) { + return null; + } + return { + + 'exclusionPatterns': value.exclusionPatterns, + 'importPaths': value.importPaths, + 'isVisible': value.isVisible, + 'isWatched': value.isWatched, + 'name': value.name, + 'type': LibraryTypeToJSON(value.type), + }; +} + diff --git a/open-api/typescript-sdk/fetch-client/models/CreateProfileImageResponseDto.ts b/open-api/typescript-sdk/fetch-client/models/CreateProfileImageResponseDto.ts new file mode 100644 index 0000000000..bcc8895693 --- /dev/null +++ b/open-api/typescript-sdk/fetch-client/models/CreateProfileImageResponseDto.ts @@ -0,0 +1,75 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * Immich + * Immich API + * + * The version of the OpenAPI document: 1.94.1 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + +import { exists, mapValues } from '../runtime'; +/** + * + * @export + * @interface CreateProfileImageResponseDto + */ +export interface CreateProfileImageResponseDto { + /** + * + * @type {string} + * @memberof CreateProfileImageResponseDto + */ + profileImagePath: string; + /** + * + * @type {string} + * @memberof CreateProfileImageResponseDto + */ + userId: string; +} + +/** + * Check if a given object implements the CreateProfileImageResponseDto interface. + */ +export function instanceOfCreateProfileImageResponseDto(value: object): boolean { + let isInstance = true; + isInstance = isInstance && "profileImagePath" in value; + isInstance = isInstance && "userId" in value; + + return isInstance; +} + +export function CreateProfileImageResponseDtoFromJSON(json: any): CreateProfileImageResponseDto { + return CreateProfileImageResponseDtoFromJSONTyped(json, false); +} + +export function CreateProfileImageResponseDtoFromJSONTyped(json: any, ignoreDiscriminator: boolean): CreateProfileImageResponseDto { + if ((json === undefined) || (json === null)) { + return json; + } + return { + + 'profileImagePath': json['profileImagePath'], + 'userId': json['userId'], + }; +} + +export function CreateProfileImageResponseDtoToJSON(value?: CreateProfileImageResponseDto | null): any { + if (value === undefined) { + return undefined; + } + if (value === null) { + return null; + } + return { + + 'profileImagePath': value.profileImagePath, + 'userId': value.userId, + }; +} + diff --git a/open-api/typescript-sdk/fetch-client/models/CreateTagDto.ts b/open-api/typescript-sdk/fetch-client/models/CreateTagDto.ts new file mode 100644 index 0000000000..fc52e0e5bc --- /dev/null +++ b/open-api/typescript-sdk/fetch-client/models/CreateTagDto.ts @@ -0,0 +1,82 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * Immich + * Immich API + * + * The version of the OpenAPI document: 1.94.1 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + +import { exists, mapValues } from '../runtime'; +import type { TagTypeEnum } from './TagTypeEnum'; +import { + TagTypeEnumFromJSON, + TagTypeEnumFromJSONTyped, + TagTypeEnumToJSON, +} from './TagTypeEnum'; + +/** + * + * @export + * @interface CreateTagDto + */ +export interface CreateTagDto { + /** + * + * @type {string} + * @memberof CreateTagDto + */ + name: string; + /** + * + * @type {TagTypeEnum} + * @memberof CreateTagDto + */ + type: TagTypeEnum; +} + +/** + * Check if a given object implements the CreateTagDto interface. + */ +export function instanceOfCreateTagDto(value: object): boolean { + let isInstance = true; + isInstance = isInstance && "name" in value; + isInstance = isInstance && "type" in value; + + return isInstance; +} + +export function CreateTagDtoFromJSON(json: any): CreateTagDto { + return CreateTagDtoFromJSONTyped(json, false); +} + +export function CreateTagDtoFromJSONTyped(json: any, ignoreDiscriminator: boolean): CreateTagDto { + if ((json === undefined) || (json === null)) { + return json; + } + return { + + 'name': json['name'], + 'type': TagTypeEnumFromJSON(json['type']), + }; +} + +export function CreateTagDtoToJSON(value?: CreateTagDto | null): any { + if (value === undefined) { + return undefined; + } + if (value === null) { + return null; + } + return { + + 'name': value.name, + 'type': TagTypeEnumToJSON(value.type), + }; +} + diff --git a/open-api/typescript-sdk/fetch-client/models/CreateUserDto.ts b/open-api/typescript-sdk/fetch-client/models/CreateUserDto.ts new file mode 100644 index 0000000000..df8efbc298 --- /dev/null +++ b/open-api/typescript-sdk/fetch-client/models/CreateUserDto.ts @@ -0,0 +1,116 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * Immich + * Immich API + * + * The version of the OpenAPI document: 1.94.1 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + +import { exists, mapValues } from '../runtime'; +/** + * + * @export + * @interface CreateUserDto + */ +export interface CreateUserDto { + /** + * + * @type {string} + * @memberof CreateUserDto + */ + email: string; + /** + * + * @type {string} + * @memberof CreateUserDto + */ + externalPath?: string | null; + /** + * + * @type {boolean} + * @memberof CreateUserDto + */ + memoriesEnabled?: boolean; + /** + * + * @type {string} + * @memberof CreateUserDto + */ + name: string; + /** + * + * @type {string} + * @memberof CreateUserDto + */ + password: string; + /** + * + * @type {number} + * @memberof CreateUserDto + */ + quotaSizeInBytes?: number | null; + /** + * + * @type {string} + * @memberof CreateUserDto + */ + storageLabel?: string | null; +} + +/** + * Check if a given object implements the CreateUserDto interface. + */ +export function instanceOfCreateUserDto(value: object): boolean { + let isInstance = true; + isInstance = isInstance && "email" in value; + isInstance = isInstance && "name" in value; + isInstance = isInstance && "password" in value; + + return isInstance; +} + +export function CreateUserDtoFromJSON(json: any): CreateUserDto { + return CreateUserDtoFromJSONTyped(json, false); +} + +export function CreateUserDtoFromJSONTyped(json: any, ignoreDiscriminator: boolean): CreateUserDto { + if ((json === undefined) || (json === null)) { + return json; + } + return { + + 'email': json['email'], + 'externalPath': !exists(json, 'externalPath') ? undefined : json['externalPath'], + 'memoriesEnabled': !exists(json, 'memoriesEnabled') ? undefined : json['memoriesEnabled'], + 'name': json['name'], + 'password': json['password'], + 'quotaSizeInBytes': !exists(json, 'quotaSizeInBytes') ? undefined : json['quotaSizeInBytes'], + 'storageLabel': !exists(json, 'storageLabel') ? undefined : json['storageLabel'], + }; +} + +export function CreateUserDtoToJSON(value?: CreateUserDto | null): any { + if (value === undefined) { + return undefined; + } + if (value === null) { + return null; + } + return { + + 'email': value.email, + 'externalPath': value.externalPath, + 'memoriesEnabled': value.memoriesEnabled, + 'name': value.name, + 'password': value.password, + 'quotaSizeInBytes': value.quotaSizeInBytes, + 'storageLabel': value.storageLabel, + }; +} + diff --git a/open-api/typescript-sdk/fetch-client/models/CuratedLocationsResponseDto.ts b/open-api/typescript-sdk/fetch-client/models/CuratedLocationsResponseDto.ts new file mode 100644 index 0000000000..dc4940e7ea --- /dev/null +++ b/open-api/typescript-sdk/fetch-client/models/CuratedLocationsResponseDto.ts @@ -0,0 +1,102 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * Immich + * Immich API + * + * The version of the OpenAPI document: 1.94.1 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + +import { exists, mapValues } from '../runtime'; +/** + * + * @export + * @interface CuratedLocationsResponseDto + */ +export interface CuratedLocationsResponseDto { + /** + * + * @type {string} + * @memberof CuratedLocationsResponseDto + */ + city: string; + /** + * + * @type {string} + * @memberof CuratedLocationsResponseDto + */ + deviceAssetId: string; + /** + * + * @type {string} + * @memberof CuratedLocationsResponseDto + */ + deviceId: string; + /** + * + * @type {string} + * @memberof CuratedLocationsResponseDto + */ + id: string; + /** + * + * @type {string} + * @memberof CuratedLocationsResponseDto + */ + resizePath: string; +} + +/** + * Check if a given object implements the CuratedLocationsResponseDto interface. + */ +export function instanceOfCuratedLocationsResponseDto(value: object): boolean { + let isInstance = true; + isInstance = isInstance && "city" in value; + isInstance = isInstance && "deviceAssetId" in value; + isInstance = isInstance && "deviceId" in value; + isInstance = isInstance && "id" in value; + isInstance = isInstance && "resizePath" in value; + + return isInstance; +} + +export function CuratedLocationsResponseDtoFromJSON(json: any): CuratedLocationsResponseDto { + return CuratedLocationsResponseDtoFromJSONTyped(json, false); +} + +export function CuratedLocationsResponseDtoFromJSONTyped(json: any, ignoreDiscriminator: boolean): CuratedLocationsResponseDto { + if ((json === undefined) || (json === null)) { + return json; + } + return { + + 'city': json['city'], + 'deviceAssetId': json['deviceAssetId'], + 'deviceId': json['deviceId'], + 'id': json['id'], + 'resizePath': json['resizePath'], + }; +} + +export function CuratedLocationsResponseDtoToJSON(value?: CuratedLocationsResponseDto | null): any { + if (value === undefined) { + return undefined; + } + if (value === null) { + return null; + } + return { + + 'city': value.city, + 'deviceAssetId': value.deviceAssetId, + 'deviceId': value.deviceId, + 'id': value.id, + 'resizePath': value.resizePath, + }; +} + diff --git a/open-api/typescript-sdk/fetch-client/models/CuratedObjectsResponseDto.ts b/open-api/typescript-sdk/fetch-client/models/CuratedObjectsResponseDto.ts new file mode 100644 index 0000000000..6366d2128b --- /dev/null +++ b/open-api/typescript-sdk/fetch-client/models/CuratedObjectsResponseDto.ts @@ -0,0 +1,102 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * Immich + * Immich API + * + * The version of the OpenAPI document: 1.94.1 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + +import { exists, mapValues } from '../runtime'; +/** + * + * @export + * @interface CuratedObjectsResponseDto + */ +export interface CuratedObjectsResponseDto { + /** + * + * @type {string} + * @memberof CuratedObjectsResponseDto + */ + deviceAssetId: string; + /** + * + * @type {string} + * @memberof CuratedObjectsResponseDto + */ + deviceId: string; + /** + * + * @type {string} + * @memberof CuratedObjectsResponseDto + */ + id: string; + /** + * + * @type {string} + * @memberof CuratedObjectsResponseDto + */ + object: string; + /** + * + * @type {string} + * @memberof CuratedObjectsResponseDto + */ + resizePath: string; +} + +/** + * Check if a given object implements the CuratedObjectsResponseDto interface. + */ +export function instanceOfCuratedObjectsResponseDto(value: object): boolean { + let isInstance = true; + isInstance = isInstance && "deviceAssetId" in value; + isInstance = isInstance && "deviceId" in value; + isInstance = isInstance && "id" in value; + isInstance = isInstance && "object" in value; + isInstance = isInstance && "resizePath" in value; + + return isInstance; +} + +export function CuratedObjectsResponseDtoFromJSON(json: any): CuratedObjectsResponseDto { + return CuratedObjectsResponseDtoFromJSONTyped(json, false); +} + +export function CuratedObjectsResponseDtoFromJSONTyped(json: any, ignoreDiscriminator: boolean): CuratedObjectsResponseDto { + if ((json === undefined) || (json === null)) { + return json; + } + return { + + 'deviceAssetId': json['deviceAssetId'], + 'deviceId': json['deviceId'], + 'id': json['id'], + 'object': json['object'], + 'resizePath': json['resizePath'], + }; +} + +export function CuratedObjectsResponseDtoToJSON(value?: CuratedObjectsResponseDto | null): any { + if (value === undefined) { + return undefined; + } + if (value === null) { + return null; + } + return { + + 'deviceAssetId': value.deviceAssetId, + 'deviceId': value.deviceId, + 'id': value.id, + 'object': value.object, + 'resizePath': value.resizePath, + }; +} + diff --git a/open-api/typescript-sdk/fetch-client/models/DownloadArchiveInfo.ts b/open-api/typescript-sdk/fetch-client/models/DownloadArchiveInfo.ts new file mode 100644 index 0000000000..916b4f932f --- /dev/null +++ b/open-api/typescript-sdk/fetch-client/models/DownloadArchiveInfo.ts @@ -0,0 +1,75 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * Immich + * Immich API + * + * The version of the OpenAPI document: 1.94.1 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + +import { exists, mapValues } from '../runtime'; +/** + * + * @export + * @interface DownloadArchiveInfo + */ +export interface DownloadArchiveInfo { + /** + * + * @type {Array} + * @memberof DownloadArchiveInfo + */ + assetIds: Array; + /** + * + * @type {number} + * @memberof DownloadArchiveInfo + */ + size: number; +} + +/** + * Check if a given object implements the DownloadArchiveInfo interface. + */ +export function instanceOfDownloadArchiveInfo(value: object): boolean { + let isInstance = true; + isInstance = isInstance && "assetIds" in value; + isInstance = isInstance && "size" in value; + + return isInstance; +} + +export function DownloadArchiveInfoFromJSON(json: any): DownloadArchiveInfo { + return DownloadArchiveInfoFromJSONTyped(json, false); +} + +export function DownloadArchiveInfoFromJSONTyped(json: any, ignoreDiscriminator: boolean): DownloadArchiveInfo { + if ((json === undefined) || (json === null)) { + return json; + } + return { + + 'assetIds': json['assetIds'], + 'size': json['size'], + }; +} + +export function DownloadArchiveInfoToJSON(value?: DownloadArchiveInfo | null): any { + if (value === undefined) { + return undefined; + } + if (value === null) { + return null; + } + return { + + 'assetIds': value.assetIds, + 'size': value.size, + }; +} + diff --git a/open-api/typescript-sdk/fetch-client/models/DownloadInfoDto.ts b/open-api/typescript-sdk/fetch-client/models/DownloadInfoDto.ts new file mode 100644 index 0000000000..7fbd55ed46 --- /dev/null +++ b/open-api/typescript-sdk/fetch-client/models/DownloadInfoDto.ts @@ -0,0 +1,89 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * Immich + * Immich API + * + * The version of the OpenAPI document: 1.94.1 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + +import { exists, mapValues } from '../runtime'; +/** + * + * @export + * @interface DownloadInfoDto + */ +export interface DownloadInfoDto { + /** + * + * @type {string} + * @memberof DownloadInfoDto + */ + albumId?: string; + /** + * + * @type {number} + * @memberof DownloadInfoDto + */ + archiveSize?: number; + /** + * + * @type {Array} + * @memberof DownloadInfoDto + */ + assetIds?: Array; + /** + * + * @type {string} + * @memberof DownloadInfoDto + */ + userId?: string; +} + +/** + * Check if a given object implements the DownloadInfoDto interface. + */ +export function instanceOfDownloadInfoDto(value: object): boolean { + let isInstance = true; + + return isInstance; +} + +export function DownloadInfoDtoFromJSON(json: any): DownloadInfoDto { + return DownloadInfoDtoFromJSONTyped(json, false); +} + +export function DownloadInfoDtoFromJSONTyped(json: any, ignoreDiscriminator: boolean): DownloadInfoDto { + if ((json === undefined) || (json === null)) { + return json; + } + return { + + 'albumId': !exists(json, 'albumId') ? undefined : json['albumId'], + 'archiveSize': !exists(json, 'archiveSize') ? undefined : json['archiveSize'], + 'assetIds': !exists(json, 'assetIds') ? undefined : json['assetIds'], + 'userId': !exists(json, 'userId') ? undefined : json['userId'], + }; +} + +export function DownloadInfoDtoToJSON(value?: DownloadInfoDto | null): any { + if (value === undefined) { + return undefined; + } + if (value === null) { + return null; + } + return { + + 'albumId': value.albumId, + 'archiveSize': value.archiveSize, + 'assetIds': value.assetIds, + 'userId': value.userId, + }; +} + diff --git a/open-api/typescript-sdk/fetch-client/models/DownloadResponseDto.ts b/open-api/typescript-sdk/fetch-client/models/DownloadResponseDto.ts new file mode 100644 index 0000000000..a0887dab8e --- /dev/null +++ b/open-api/typescript-sdk/fetch-client/models/DownloadResponseDto.ts @@ -0,0 +1,82 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * Immich + * Immich API + * + * The version of the OpenAPI document: 1.94.1 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + +import { exists, mapValues } from '../runtime'; +import type { DownloadArchiveInfo } from './DownloadArchiveInfo'; +import { + DownloadArchiveInfoFromJSON, + DownloadArchiveInfoFromJSONTyped, + DownloadArchiveInfoToJSON, +} from './DownloadArchiveInfo'; + +/** + * + * @export + * @interface DownloadResponseDto + */ +export interface DownloadResponseDto { + /** + * + * @type {Array} + * @memberof DownloadResponseDto + */ + archives: Array; + /** + * + * @type {number} + * @memberof DownloadResponseDto + */ + totalSize: number; +} + +/** + * Check if a given object implements the DownloadResponseDto interface. + */ +export function instanceOfDownloadResponseDto(value: object): boolean { + let isInstance = true; + isInstance = isInstance && "archives" in value; + isInstance = isInstance && "totalSize" in value; + + return isInstance; +} + +export function DownloadResponseDtoFromJSON(json: any): DownloadResponseDto { + return DownloadResponseDtoFromJSONTyped(json, false); +} + +export function DownloadResponseDtoFromJSONTyped(json: any, ignoreDiscriminator: boolean): DownloadResponseDto { + if ((json === undefined) || (json === null)) { + return json; + } + return { + + 'archives': ((json['archives'] as Array).map(DownloadArchiveInfoFromJSON)), + 'totalSize': json['totalSize'], + }; +} + +export function DownloadResponseDtoToJSON(value?: DownloadResponseDto | null): any { + if (value === undefined) { + return undefined; + } + if (value === null) { + return null; + } + return { + + 'archives': ((value.archives as Array).map(DownloadArchiveInfoToJSON)), + 'totalSize': value.totalSize, + }; +} + diff --git a/open-api/typescript-sdk/fetch-client/models/EntityType.ts b/open-api/typescript-sdk/fetch-client/models/EntityType.ts new file mode 100644 index 0000000000..c5b9abb9ac --- /dev/null +++ b/open-api/typescript-sdk/fetch-client/models/EntityType.ts @@ -0,0 +1,38 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * Immich + * Immich API + * + * The version of the OpenAPI document: 1.94.1 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + + +/** + * + * @export + */ +export const EntityType = { + Asset: 'ASSET', + Album: 'ALBUM' +} as const; +export type EntityType = typeof EntityType[keyof typeof EntityType]; + + +export function EntityTypeFromJSON(json: any): EntityType { + return EntityTypeFromJSONTyped(json, false); +} + +export function EntityTypeFromJSONTyped(json: any, ignoreDiscriminator: boolean): EntityType { + return json as EntityType; +} + +export function EntityTypeToJSON(value?: EntityType | null): any { + return value as any; +} + diff --git a/open-api/typescript-sdk/fetch-client/models/ExifResponseDto.ts b/open-api/typescript-sdk/fetch-client/models/ExifResponseDto.ts new file mode 100644 index 0000000000..c0ce31edc3 --- /dev/null +++ b/open-api/typescript-sdk/fetch-client/models/ExifResponseDto.ts @@ -0,0 +1,225 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * Immich + * Immich API + * + * The version of the OpenAPI document: 1.94.1 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + +import { exists, mapValues } from '../runtime'; +/** + * + * @export + * @interface ExifResponseDto + */ +export interface ExifResponseDto { + /** + * + * @type {string} + * @memberof ExifResponseDto + */ + city?: string | null; + /** + * + * @type {string} + * @memberof ExifResponseDto + */ + country?: string | null; + /** + * + * @type {Date} + * @memberof ExifResponseDto + */ + dateTimeOriginal?: Date | null; + /** + * + * @type {string} + * @memberof ExifResponseDto + */ + description?: string | null; + /** + * + * @type {number} + * @memberof ExifResponseDto + */ + exifImageHeight?: number | null; + /** + * + * @type {number} + * @memberof ExifResponseDto + */ + exifImageWidth?: number | null; + /** + * + * @type {string} + * @memberof ExifResponseDto + */ + exposureTime?: string | null; + /** + * + * @type {number} + * @memberof ExifResponseDto + */ + fNumber?: number | null; + /** + * + * @type {number} + * @memberof ExifResponseDto + */ + fileSizeInByte?: number | null; + /** + * + * @type {number} + * @memberof ExifResponseDto + */ + focalLength?: number | null; + /** + * + * @type {number} + * @memberof ExifResponseDto + */ + iso?: number | null; + /** + * + * @type {number} + * @memberof ExifResponseDto + */ + latitude?: number | null; + /** + * + * @type {string} + * @memberof ExifResponseDto + */ + lensModel?: string | null; + /** + * + * @type {number} + * @memberof ExifResponseDto + */ + longitude?: number | null; + /** + * + * @type {string} + * @memberof ExifResponseDto + */ + make?: string | null; + /** + * + * @type {string} + * @memberof ExifResponseDto + */ + model?: string | null; + /** + * + * @type {Date} + * @memberof ExifResponseDto + */ + modifyDate?: Date | null; + /** + * + * @type {string} + * @memberof ExifResponseDto + */ + orientation?: string | null; + /** + * + * @type {string} + * @memberof ExifResponseDto + */ + projectionType?: string | null; + /** + * + * @type {string} + * @memberof ExifResponseDto + */ + state?: string | null; + /** + * + * @type {string} + * @memberof ExifResponseDto + */ + timeZone?: string | null; +} + +/** + * Check if a given object implements the ExifResponseDto interface. + */ +export function instanceOfExifResponseDto(value: object): boolean { + let isInstance = true; + + return isInstance; +} + +export function ExifResponseDtoFromJSON(json: any): ExifResponseDto { + return ExifResponseDtoFromJSONTyped(json, false); +} + +export function ExifResponseDtoFromJSONTyped(json: any, ignoreDiscriminator: boolean): ExifResponseDto { + if ((json === undefined) || (json === null)) { + return json; + } + return { + + 'city': !exists(json, 'city') ? undefined : json['city'], + 'country': !exists(json, 'country') ? undefined : json['country'], + 'dateTimeOriginal': !exists(json, 'dateTimeOriginal') ? undefined : (json['dateTimeOriginal'] === null ? null : new Date(json['dateTimeOriginal'])), + 'description': !exists(json, 'description') ? undefined : json['description'], + 'exifImageHeight': !exists(json, 'exifImageHeight') ? undefined : json['exifImageHeight'], + 'exifImageWidth': !exists(json, 'exifImageWidth') ? undefined : json['exifImageWidth'], + 'exposureTime': !exists(json, 'exposureTime') ? undefined : json['exposureTime'], + 'fNumber': !exists(json, 'fNumber') ? undefined : json['fNumber'], + 'fileSizeInByte': !exists(json, 'fileSizeInByte') ? undefined : json['fileSizeInByte'], + 'focalLength': !exists(json, 'focalLength') ? undefined : json['focalLength'], + 'iso': !exists(json, 'iso') ? undefined : json['iso'], + 'latitude': !exists(json, 'latitude') ? undefined : json['latitude'], + 'lensModel': !exists(json, 'lensModel') ? undefined : json['lensModel'], + 'longitude': !exists(json, 'longitude') ? undefined : json['longitude'], + 'make': !exists(json, 'make') ? undefined : json['make'], + 'model': !exists(json, 'model') ? undefined : json['model'], + 'modifyDate': !exists(json, 'modifyDate') ? undefined : (json['modifyDate'] === null ? null : new Date(json['modifyDate'])), + 'orientation': !exists(json, 'orientation') ? undefined : json['orientation'], + 'projectionType': !exists(json, 'projectionType') ? undefined : json['projectionType'], + 'state': !exists(json, 'state') ? undefined : json['state'], + 'timeZone': !exists(json, 'timeZone') ? undefined : json['timeZone'], + }; +} + +export function ExifResponseDtoToJSON(value?: ExifResponseDto | null): any { + if (value === undefined) { + return undefined; + } + if (value === null) { + return null; + } + return { + + 'city': value.city, + 'country': value.country, + 'dateTimeOriginal': value.dateTimeOriginal === undefined ? undefined : (value.dateTimeOriginal === null ? null : value.dateTimeOriginal.toISOString()), + 'description': value.description, + 'exifImageHeight': value.exifImageHeight, + 'exifImageWidth': value.exifImageWidth, + 'exposureTime': value.exposureTime, + 'fNumber': value.fNumber, + 'fileSizeInByte': value.fileSizeInByte, + 'focalLength': value.focalLength, + 'iso': value.iso, + 'latitude': value.latitude, + 'lensModel': value.lensModel, + 'longitude': value.longitude, + 'make': value.make, + 'model': value.model, + 'modifyDate': value.modifyDate === undefined ? undefined : (value.modifyDate === null ? null : value.modifyDate.toISOString()), + 'orientation': value.orientation, + 'projectionType': value.projectionType, + 'state': value.state, + 'timeZone': value.timeZone, + }; +} + diff --git a/open-api/typescript-sdk/fetch-client/models/FaceDto.ts b/open-api/typescript-sdk/fetch-client/models/FaceDto.ts new file mode 100644 index 0000000000..01a18d6efd --- /dev/null +++ b/open-api/typescript-sdk/fetch-client/models/FaceDto.ts @@ -0,0 +1,66 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * Immich + * Immich API + * + * The version of the OpenAPI document: 1.94.1 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + +import { exists, mapValues } from '../runtime'; +/** + * + * @export + * @interface FaceDto + */ +export interface FaceDto { + /** + * + * @type {string} + * @memberof FaceDto + */ + id: string; +} + +/** + * Check if a given object implements the FaceDto interface. + */ +export function instanceOfFaceDto(value: object): boolean { + let isInstance = true; + isInstance = isInstance && "id" in value; + + return isInstance; +} + +export function FaceDtoFromJSON(json: any): FaceDto { + return FaceDtoFromJSONTyped(json, false); +} + +export function FaceDtoFromJSONTyped(json: any, ignoreDiscriminator: boolean): FaceDto { + if ((json === undefined) || (json === null)) { + return json; + } + return { + + 'id': json['id'], + }; +} + +export function FaceDtoToJSON(value?: FaceDto | null): any { + if (value === undefined) { + return undefined; + } + if (value === null) { + return null; + } + return { + + 'id': value.id, + }; +} + diff --git a/open-api/typescript-sdk/fetch-client/models/FileChecksumDto.ts b/open-api/typescript-sdk/fetch-client/models/FileChecksumDto.ts new file mode 100644 index 0000000000..9c924bfe88 --- /dev/null +++ b/open-api/typescript-sdk/fetch-client/models/FileChecksumDto.ts @@ -0,0 +1,66 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * Immich + * Immich API + * + * The version of the OpenAPI document: 1.94.1 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + +import { exists, mapValues } from '../runtime'; +/** + * + * @export + * @interface FileChecksumDto + */ +export interface FileChecksumDto { + /** + * + * @type {Array} + * @memberof FileChecksumDto + */ + filenames: Array; +} + +/** + * Check if a given object implements the FileChecksumDto interface. + */ +export function instanceOfFileChecksumDto(value: object): boolean { + let isInstance = true; + isInstance = isInstance && "filenames" in value; + + return isInstance; +} + +export function FileChecksumDtoFromJSON(json: any): FileChecksumDto { + return FileChecksumDtoFromJSONTyped(json, false); +} + +export function FileChecksumDtoFromJSONTyped(json: any, ignoreDiscriminator: boolean): FileChecksumDto { + if ((json === undefined) || (json === null)) { + return json; + } + return { + + 'filenames': json['filenames'], + }; +} + +export function FileChecksumDtoToJSON(value?: FileChecksumDto | null): any { + if (value === undefined) { + return undefined; + } + if (value === null) { + return null; + } + return { + + 'filenames': value.filenames, + }; +} + diff --git a/open-api/typescript-sdk/fetch-client/models/FileChecksumResponseDto.ts b/open-api/typescript-sdk/fetch-client/models/FileChecksumResponseDto.ts new file mode 100644 index 0000000000..734822c48b --- /dev/null +++ b/open-api/typescript-sdk/fetch-client/models/FileChecksumResponseDto.ts @@ -0,0 +1,75 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * Immich + * Immich API + * + * The version of the OpenAPI document: 1.94.1 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + +import { exists, mapValues } from '../runtime'; +/** + * + * @export + * @interface FileChecksumResponseDto + */ +export interface FileChecksumResponseDto { + /** + * + * @type {string} + * @memberof FileChecksumResponseDto + */ + checksum: string; + /** + * + * @type {string} + * @memberof FileChecksumResponseDto + */ + filename: string; +} + +/** + * Check if a given object implements the FileChecksumResponseDto interface. + */ +export function instanceOfFileChecksumResponseDto(value: object): boolean { + let isInstance = true; + isInstance = isInstance && "checksum" in value; + isInstance = isInstance && "filename" in value; + + return isInstance; +} + +export function FileChecksumResponseDtoFromJSON(json: any): FileChecksumResponseDto { + return FileChecksumResponseDtoFromJSONTyped(json, false); +} + +export function FileChecksumResponseDtoFromJSONTyped(json: any, ignoreDiscriminator: boolean): FileChecksumResponseDto { + if ((json === undefined) || (json === null)) { + return json; + } + return { + + 'checksum': json['checksum'], + 'filename': json['filename'], + }; +} + +export function FileChecksumResponseDtoToJSON(value?: FileChecksumResponseDto | null): any { + if (value === undefined) { + return undefined; + } + if (value === null) { + return null; + } + return { + + 'checksum': value.checksum, + 'filename': value.filename, + }; +} + diff --git a/open-api/typescript-sdk/fetch-client/models/FileReportDto.ts b/open-api/typescript-sdk/fetch-client/models/FileReportDto.ts new file mode 100644 index 0000000000..5dd66d63a5 --- /dev/null +++ b/open-api/typescript-sdk/fetch-client/models/FileReportDto.ts @@ -0,0 +1,82 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * Immich + * Immich API + * + * The version of the OpenAPI document: 1.94.1 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + +import { exists, mapValues } from '../runtime'; +import type { FileReportItemDto } from './FileReportItemDto'; +import { + FileReportItemDtoFromJSON, + FileReportItemDtoFromJSONTyped, + FileReportItemDtoToJSON, +} from './FileReportItemDto'; + +/** + * + * @export + * @interface FileReportDto + */ +export interface FileReportDto { + /** + * + * @type {Array} + * @memberof FileReportDto + */ + extras: Array; + /** + * + * @type {Array} + * @memberof FileReportDto + */ + orphans: Array; +} + +/** + * Check if a given object implements the FileReportDto interface. + */ +export function instanceOfFileReportDto(value: object): boolean { + let isInstance = true; + isInstance = isInstance && "extras" in value; + isInstance = isInstance && "orphans" in value; + + return isInstance; +} + +export function FileReportDtoFromJSON(json: any): FileReportDto { + return FileReportDtoFromJSONTyped(json, false); +} + +export function FileReportDtoFromJSONTyped(json: any, ignoreDiscriminator: boolean): FileReportDto { + if ((json === undefined) || (json === null)) { + return json; + } + return { + + 'extras': json['extras'], + 'orphans': ((json['orphans'] as Array).map(FileReportItemDtoFromJSON)), + }; +} + +export function FileReportDtoToJSON(value?: FileReportDto | null): any { + if (value === undefined) { + return undefined; + } + if (value === null) { + return null; + } + return { + + 'extras': value.extras, + 'orphans': ((value.orphans as Array).map(FileReportItemDtoToJSON)), + }; +} + diff --git a/open-api/typescript-sdk/fetch-client/models/FileReportFixDto.ts b/open-api/typescript-sdk/fetch-client/models/FileReportFixDto.ts new file mode 100644 index 0000000000..ec651a58dd --- /dev/null +++ b/open-api/typescript-sdk/fetch-client/models/FileReportFixDto.ts @@ -0,0 +1,73 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * Immich + * Immich API + * + * The version of the OpenAPI document: 1.94.1 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + +import { exists, mapValues } from '../runtime'; +import type { FileReportItemDto } from './FileReportItemDto'; +import { + FileReportItemDtoFromJSON, + FileReportItemDtoFromJSONTyped, + FileReportItemDtoToJSON, +} from './FileReportItemDto'; + +/** + * + * @export + * @interface FileReportFixDto + */ +export interface FileReportFixDto { + /** + * + * @type {Array} + * @memberof FileReportFixDto + */ + items: Array; +} + +/** + * Check if a given object implements the FileReportFixDto interface. + */ +export function instanceOfFileReportFixDto(value: object): boolean { + let isInstance = true; + isInstance = isInstance && "items" in value; + + return isInstance; +} + +export function FileReportFixDtoFromJSON(json: any): FileReportFixDto { + return FileReportFixDtoFromJSONTyped(json, false); +} + +export function FileReportFixDtoFromJSONTyped(json: any, ignoreDiscriminator: boolean): FileReportFixDto { + if ((json === undefined) || (json === null)) { + return json; + } + return { + + 'items': ((json['items'] as Array).map(FileReportItemDtoFromJSON)), + }; +} + +export function FileReportFixDtoToJSON(value?: FileReportFixDto | null): any { + if (value === undefined) { + return undefined; + } + if (value === null) { + return null; + } + return { + + 'items': ((value.items as Array).map(FileReportItemDtoToJSON)), + }; +} + diff --git a/open-api/typescript-sdk/fetch-client/models/FileReportItemDto.ts b/open-api/typescript-sdk/fetch-client/models/FileReportItemDto.ts new file mode 100644 index 0000000000..12652f9a69 --- /dev/null +++ b/open-api/typescript-sdk/fetch-client/models/FileReportItemDto.ts @@ -0,0 +1,114 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * Immich + * Immich API + * + * The version of the OpenAPI document: 1.94.1 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + +import { exists, mapValues } from '../runtime'; +import type { PathEntityType } from './PathEntityType'; +import { + PathEntityTypeFromJSON, + PathEntityTypeFromJSONTyped, + PathEntityTypeToJSON, +} from './PathEntityType'; +import type { PathType } from './PathType'; +import { + PathTypeFromJSON, + PathTypeFromJSONTyped, + PathTypeToJSON, +} from './PathType'; + +/** + * + * @export + * @interface FileReportItemDto + */ +export interface FileReportItemDto { + /** + * + * @type {string} + * @memberof FileReportItemDto + */ + checksum?: string; + /** + * + * @type {string} + * @memberof FileReportItemDto + */ + entityId: string; + /** + * + * @type {PathEntityType} + * @memberof FileReportItemDto + */ + entityType: PathEntityType; + /** + * + * @type {PathType} + * @memberof FileReportItemDto + */ + pathType: PathType; + /** + * + * @type {string} + * @memberof FileReportItemDto + */ + pathValue: string; +} + +/** + * Check if a given object implements the FileReportItemDto interface. + */ +export function instanceOfFileReportItemDto(value: object): boolean { + let isInstance = true; + isInstance = isInstance && "entityId" in value; + isInstance = isInstance && "entityType" in value; + isInstance = isInstance && "pathType" in value; + isInstance = isInstance && "pathValue" in value; + + return isInstance; +} + +export function FileReportItemDtoFromJSON(json: any): FileReportItemDto { + return FileReportItemDtoFromJSONTyped(json, false); +} + +export function FileReportItemDtoFromJSONTyped(json: any, ignoreDiscriminator: boolean): FileReportItemDto { + if ((json === undefined) || (json === null)) { + return json; + } + return { + + 'checksum': !exists(json, 'checksum') ? undefined : json['checksum'], + 'entityId': json['entityId'], + 'entityType': PathEntityTypeFromJSON(json['entityType']), + 'pathType': PathTypeFromJSON(json['pathType']), + 'pathValue': json['pathValue'], + }; +} + +export function FileReportItemDtoToJSON(value?: FileReportItemDto | null): any { + if (value === undefined) { + return undefined; + } + if (value === null) { + return null; + } + return { + + 'checksum': value.checksum, + 'entityId': value.entityId, + 'entityType': PathEntityTypeToJSON(value.entityType), + 'pathType': PathTypeToJSON(value.pathType), + 'pathValue': value.pathValue, + }; +} + diff --git a/open-api/typescript-sdk/fetch-client/models/JobCommand.ts b/open-api/typescript-sdk/fetch-client/models/JobCommand.ts new file mode 100644 index 0000000000..5f4c03d41b --- /dev/null +++ b/open-api/typescript-sdk/fetch-client/models/JobCommand.ts @@ -0,0 +1,41 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * Immich + * Immich API + * + * The version of the OpenAPI document: 1.94.1 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + + +/** + * + * @export + */ +export const JobCommand = { + Start: 'start', + Pause: 'pause', + Resume: 'resume', + Empty: 'empty', + ClearFailed: 'clear-failed' +} as const; +export type JobCommand = typeof JobCommand[keyof typeof JobCommand]; + + +export function JobCommandFromJSON(json: any): JobCommand { + return JobCommandFromJSONTyped(json, false); +} + +export function JobCommandFromJSONTyped(json: any, ignoreDiscriminator: boolean): JobCommand { + return json as JobCommand; +} + +export function JobCommandToJSON(value?: JobCommand | null): any { + return value as any; +} + diff --git a/open-api/typescript-sdk/fetch-client/models/JobCommandDto.ts b/open-api/typescript-sdk/fetch-client/models/JobCommandDto.ts new file mode 100644 index 0000000000..7faf938249 --- /dev/null +++ b/open-api/typescript-sdk/fetch-client/models/JobCommandDto.ts @@ -0,0 +1,82 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * Immich + * Immich API + * + * The version of the OpenAPI document: 1.94.1 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + +import { exists, mapValues } from '../runtime'; +import type { JobCommand } from './JobCommand'; +import { + JobCommandFromJSON, + JobCommandFromJSONTyped, + JobCommandToJSON, +} from './JobCommand'; + +/** + * + * @export + * @interface JobCommandDto + */ +export interface JobCommandDto { + /** + * + * @type {JobCommand} + * @memberof JobCommandDto + */ + command: JobCommand; + /** + * + * @type {boolean} + * @memberof JobCommandDto + */ + force: boolean; +} + +/** + * Check if a given object implements the JobCommandDto interface. + */ +export function instanceOfJobCommandDto(value: object): boolean { + let isInstance = true; + isInstance = isInstance && "command" in value; + isInstance = isInstance && "force" in value; + + return isInstance; +} + +export function JobCommandDtoFromJSON(json: any): JobCommandDto { + return JobCommandDtoFromJSONTyped(json, false); +} + +export function JobCommandDtoFromJSONTyped(json: any, ignoreDiscriminator: boolean): JobCommandDto { + if ((json === undefined) || (json === null)) { + return json; + } + return { + + 'command': JobCommandFromJSON(json['command']), + 'force': json['force'], + }; +} + +export function JobCommandDtoToJSON(value?: JobCommandDto | null): any { + if (value === undefined) { + return undefined; + } + if (value === null) { + return null; + } + return { + + 'command': JobCommandToJSON(value.command), + 'force': value.force, + }; +} + diff --git a/open-api/typescript-sdk/fetch-client/models/JobCountsDto.ts b/open-api/typescript-sdk/fetch-client/models/JobCountsDto.ts new file mode 100644 index 0000000000..48645a27ca --- /dev/null +++ b/open-api/typescript-sdk/fetch-client/models/JobCountsDto.ts @@ -0,0 +1,111 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * Immich + * Immich API + * + * The version of the OpenAPI document: 1.94.1 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + +import { exists, mapValues } from '../runtime'; +/** + * + * @export + * @interface JobCountsDto + */ +export interface JobCountsDto { + /** + * + * @type {number} + * @memberof JobCountsDto + */ + active: number; + /** + * + * @type {number} + * @memberof JobCountsDto + */ + completed: number; + /** + * + * @type {number} + * @memberof JobCountsDto + */ + delayed: number; + /** + * + * @type {number} + * @memberof JobCountsDto + */ + failed: number; + /** + * + * @type {number} + * @memberof JobCountsDto + */ + paused: number; + /** + * + * @type {number} + * @memberof JobCountsDto + */ + waiting: number; +} + +/** + * Check if a given object implements the JobCountsDto interface. + */ +export function instanceOfJobCountsDto(value: object): boolean { + let isInstance = true; + isInstance = isInstance && "active" in value; + isInstance = isInstance && "completed" in value; + isInstance = isInstance && "delayed" in value; + isInstance = isInstance && "failed" in value; + isInstance = isInstance && "paused" in value; + isInstance = isInstance && "waiting" in value; + + return isInstance; +} + +export function JobCountsDtoFromJSON(json: any): JobCountsDto { + return JobCountsDtoFromJSONTyped(json, false); +} + +export function JobCountsDtoFromJSONTyped(json: any, ignoreDiscriminator: boolean): JobCountsDto { + if ((json === undefined) || (json === null)) { + return json; + } + return { + + 'active': json['active'], + 'completed': json['completed'], + 'delayed': json['delayed'], + 'failed': json['failed'], + 'paused': json['paused'], + 'waiting': json['waiting'], + }; +} + +export function JobCountsDtoToJSON(value?: JobCountsDto | null): any { + if (value === undefined) { + return undefined; + } + if (value === null) { + return null; + } + return { + + 'active': value.active, + 'completed': value.completed, + 'delayed': value.delayed, + 'failed': value.failed, + 'paused': value.paused, + 'waiting': value.waiting, + }; +} + diff --git a/open-api/typescript-sdk/fetch-client/models/JobName.ts b/open-api/typescript-sdk/fetch-client/models/JobName.ts new file mode 100644 index 0000000000..714e077d9e --- /dev/null +++ b/open-api/typescript-sdk/fetch-client/models/JobName.ts @@ -0,0 +1,48 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * Immich + * Immich API + * + * The version of the OpenAPI document: 1.94.1 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + + +/** + * + * @export + */ +export const JobName = { + ThumbnailGeneration: 'thumbnailGeneration', + MetadataExtraction: 'metadataExtraction', + VideoConversion: 'videoConversion', + FaceDetection: 'faceDetection', + FacialRecognition: 'facialRecognition', + SmartSearch: 'smartSearch', + BackgroundTask: 'backgroundTask', + StorageTemplateMigration: 'storageTemplateMigration', + Migration: 'migration', + Search: 'search', + Sidecar: 'sidecar', + Library: 'library' +} as const; +export type JobName = typeof JobName[keyof typeof JobName]; + + +export function JobNameFromJSON(json: any): JobName { + return JobNameFromJSONTyped(json, false); +} + +export function JobNameFromJSONTyped(json: any, ignoreDiscriminator: boolean): JobName { + return json as JobName; +} + +export function JobNameToJSON(value?: JobName | null): any { + return value as any; +} + diff --git a/open-api/typescript-sdk/fetch-client/models/JobSettingsDto.ts b/open-api/typescript-sdk/fetch-client/models/JobSettingsDto.ts new file mode 100644 index 0000000000..bbbc819d0e --- /dev/null +++ b/open-api/typescript-sdk/fetch-client/models/JobSettingsDto.ts @@ -0,0 +1,66 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * Immich + * Immich API + * + * The version of the OpenAPI document: 1.94.1 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + +import { exists, mapValues } from '../runtime'; +/** + * + * @export + * @interface JobSettingsDto + */ +export interface JobSettingsDto { + /** + * + * @type {number} + * @memberof JobSettingsDto + */ + concurrency: number; +} + +/** + * Check if a given object implements the JobSettingsDto interface. + */ +export function instanceOfJobSettingsDto(value: object): boolean { + let isInstance = true; + isInstance = isInstance && "concurrency" in value; + + return isInstance; +} + +export function JobSettingsDtoFromJSON(json: any): JobSettingsDto { + return JobSettingsDtoFromJSONTyped(json, false); +} + +export function JobSettingsDtoFromJSONTyped(json: any, ignoreDiscriminator: boolean): JobSettingsDto { + if ((json === undefined) || (json === null)) { + return json; + } + return { + + 'concurrency': json['concurrency'], + }; +} + +export function JobSettingsDtoToJSON(value?: JobSettingsDto | null): any { + if (value === undefined) { + return undefined; + } + if (value === null) { + return null; + } + return { + + 'concurrency': value.concurrency, + }; +} + diff --git a/open-api/typescript-sdk/fetch-client/models/JobStatusDto.ts b/open-api/typescript-sdk/fetch-client/models/JobStatusDto.ts new file mode 100644 index 0000000000..32c29e10fc --- /dev/null +++ b/open-api/typescript-sdk/fetch-client/models/JobStatusDto.ts @@ -0,0 +1,88 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * Immich + * Immich API + * + * The version of the OpenAPI document: 1.94.1 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + +import { exists, mapValues } from '../runtime'; +import type { JobCountsDto } from './JobCountsDto'; +import { + JobCountsDtoFromJSON, + JobCountsDtoFromJSONTyped, + JobCountsDtoToJSON, +} from './JobCountsDto'; +import type { QueueStatusDto } from './QueueStatusDto'; +import { + QueueStatusDtoFromJSON, + QueueStatusDtoFromJSONTyped, + QueueStatusDtoToJSON, +} from './QueueStatusDto'; + +/** + * + * @export + * @interface JobStatusDto + */ +export interface JobStatusDto { + /** + * + * @type {JobCountsDto} + * @memberof JobStatusDto + */ + jobCounts: JobCountsDto; + /** + * + * @type {QueueStatusDto} + * @memberof JobStatusDto + */ + queueStatus: QueueStatusDto; +} + +/** + * Check if a given object implements the JobStatusDto interface. + */ +export function instanceOfJobStatusDto(value: object): boolean { + let isInstance = true; + isInstance = isInstance && "jobCounts" in value; + isInstance = isInstance && "queueStatus" in value; + + return isInstance; +} + +export function JobStatusDtoFromJSON(json: any): JobStatusDto { + return JobStatusDtoFromJSONTyped(json, false); +} + +export function JobStatusDtoFromJSONTyped(json: any, ignoreDiscriminator: boolean): JobStatusDto { + if ((json === undefined) || (json === null)) { + return json; + } + return { + + 'jobCounts': JobCountsDtoFromJSON(json['jobCounts']), + 'queueStatus': QueueStatusDtoFromJSON(json['queueStatus']), + }; +} + +export function JobStatusDtoToJSON(value?: JobStatusDto | null): any { + if (value === undefined) { + return undefined; + } + if (value === null) { + return null; + } + return { + + 'jobCounts': JobCountsDtoToJSON(value.jobCounts), + 'queueStatus': QueueStatusDtoToJSON(value.queueStatus), + }; +} + diff --git a/open-api/typescript-sdk/fetch-client/models/LibraryResponseDto.ts b/open-api/typescript-sdk/fetch-client/models/LibraryResponseDto.ts new file mode 100644 index 0000000000..0f64540b4b --- /dev/null +++ b/open-api/typescript-sdk/fetch-client/models/LibraryResponseDto.ts @@ -0,0 +1,154 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * Immich + * Immich API + * + * The version of the OpenAPI document: 1.94.1 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + +import { exists, mapValues } from '../runtime'; +import type { LibraryType } from './LibraryType'; +import { + LibraryTypeFromJSON, + LibraryTypeFromJSONTyped, + LibraryTypeToJSON, +} from './LibraryType'; + +/** + * + * @export + * @interface LibraryResponseDto + */ +export interface LibraryResponseDto { + /** + * + * @type {number} + * @memberof LibraryResponseDto + */ + assetCount: number; + /** + * + * @type {Date} + * @memberof LibraryResponseDto + */ + createdAt: Date; + /** + * + * @type {Array} + * @memberof LibraryResponseDto + */ + exclusionPatterns: Array; + /** + * + * @type {string} + * @memberof LibraryResponseDto + */ + id: string; + /** + * + * @type {Array} + * @memberof LibraryResponseDto + */ + importPaths: Array; + /** + * + * @type {string} + * @memberof LibraryResponseDto + */ + name: string; + /** + * + * @type {string} + * @memberof LibraryResponseDto + */ + ownerId: string; + /** + * + * @type {Date} + * @memberof LibraryResponseDto + */ + refreshedAt: Date | null; + /** + * + * @type {LibraryType} + * @memberof LibraryResponseDto + */ + type: LibraryType; + /** + * + * @type {Date} + * @memberof LibraryResponseDto + */ + updatedAt: Date; +} + +/** + * Check if a given object implements the LibraryResponseDto interface. + */ +export function instanceOfLibraryResponseDto(value: object): boolean { + let isInstance = true; + isInstance = isInstance && "assetCount" in value; + isInstance = isInstance && "createdAt" in value; + isInstance = isInstance && "exclusionPatterns" in value; + isInstance = isInstance && "id" in value; + isInstance = isInstance && "importPaths" in value; + isInstance = isInstance && "name" in value; + isInstance = isInstance && "ownerId" in value; + isInstance = isInstance && "refreshedAt" in value; + isInstance = isInstance && "type" in value; + isInstance = isInstance && "updatedAt" in value; + + return isInstance; +} + +export function LibraryResponseDtoFromJSON(json: any): LibraryResponseDto { + return LibraryResponseDtoFromJSONTyped(json, false); +} + +export function LibraryResponseDtoFromJSONTyped(json: any, ignoreDiscriminator: boolean): LibraryResponseDto { + if ((json === undefined) || (json === null)) { + return json; + } + return { + + 'assetCount': json['assetCount'], + 'createdAt': (new Date(json['createdAt'])), + 'exclusionPatterns': json['exclusionPatterns'], + 'id': json['id'], + 'importPaths': json['importPaths'], + 'name': json['name'], + 'ownerId': json['ownerId'], + 'refreshedAt': (json['refreshedAt'] === null ? null : new Date(json['refreshedAt'])), + 'type': LibraryTypeFromJSON(json['type']), + 'updatedAt': (new Date(json['updatedAt'])), + }; +} + +export function LibraryResponseDtoToJSON(value?: LibraryResponseDto | null): any { + if (value === undefined) { + return undefined; + } + if (value === null) { + return null; + } + return { + + 'assetCount': value.assetCount, + 'createdAt': (value.createdAt.toISOString()), + 'exclusionPatterns': value.exclusionPatterns, + 'id': value.id, + 'importPaths': value.importPaths, + 'name': value.name, + 'ownerId': value.ownerId, + 'refreshedAt': (value.refreshedAt === null ? null : value.refreshedAt.toISOString()), + 'type': LibraryTypeToJSON(value.type), + 'updatedAt': (value.updatedAt.toISOString()), + }; +} + diff --git a/open-api/typescript-sdk/fetch-client/models/LibraryStatsResponseDto.ts b/open-api/typescript-sdk/fetch-client/models/LibraryStatsResponseDto.ts new file mode 100644 index 0000000000..94639c35fa --- /dev/null +++ b/open-api/typescript-sdk/fetch-client/models/LibraryStatsResponseDto.ts @@ -0,0 +1,93 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * Immich + * Immich API + * + * The version of the OpenAPI document: 1.94.1 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + +import { exists, mapValues } from '../runtime'; +/** + * + * @export + * @interface LibraryStatsResponseDto + */ +export interface LibraryStatsResponseDto { + /** + * + * @type {number} + * @memberof LibraryStatsResponseDto + */ + photos: number; + /** + * + * @type {number} + * @memberof LibraryStatsResponseDto + */ + total: number; + /** + * + * @type {number} + * @memberof LibraryStatsResponseDto + */ + usage: number; + /** + * + * @type {number} + * @memberof LibraryStatsResponseDto + */ + videos: number; +} + +/** + * Check if a given object implements the LibraryStatsResponseDto interface. + */ +export function instanceOfLibraryStatsResponseDto(value: object): boolean { + let isInstance = true; + isInstance = isInstance && "photos" in value; + isInstance = isInstance && "total" in value; + isInstance = isInstance && "usage" in value; + isInstance = isInstance && "videos" in value; + + return isInstance; +} + +export function LibraryStatsResponseDtoFromJSON(json: any): LibraryStatsResponseDto { + return LibraryStatsResponseDtoFromJSONTyped(json, false); +} + +export function LibraryStatsResponseDtoFromJSONTyped(json: any, ignoreDiscriminator: boolean): LibraryStatsResponseDto { + if ((json === undefined) || (json === null)) { + return json; + } + return { + + 'photos': json['photos'], + 'total': json['total'], + 'usage': json['usage'], + 'videos': json['videos'], + }; +} + +export function LibraryStatsResponseDtoToJSON(value?: LibraryStatsResponseDto | null): any { + if (value === undefined) { + return undefined; + } + if (value === null) { + return null; + } + return { + + 'photos': value.photos, + 'total': value.total, + 'usage': value.usage, + 'videos': value.videos, + }; +} + diff --git a/open-api/typescript-sdk/fetch-client/models/LibraryType.ts b/open-api/typescript-sdk/fetch-client/models/LibraryType.ts new file mode 100644 index 0000000000..99d66218b6 --- /dev/null +++ b/open-api/typescript-sdk/fetch-client/models/LibraryType.ts @@ -0,0 +1,38 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * Immich + * Immich API + * + * The version of the OpenAPI document: 1.94.1 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + + +/** + * + * @export + */ +export const LibraryType = { + Upload: 'UPLOAD', + External: 'EXTERNAL' +} as const; +export type LibraryType = typeof LibraryType[keyof typeof LibraryType]; + + +export function LibraryTypeFromJSON(json: any): LibraryType { + return LibraryTypeFromJSONTyped(json, false); +} + +export function LibraryTypeFromJSONTyped(json: any, ignoreDiscriminator: boolean): LibraryType { + return json as LibraryType; +} + +export function LibraryTypeToJSON(value?: LibraryType | null): any { + return value as any; +} + diff --git a/open-api/typescript-sdk/fetch-client/models/LogLevel.ts b/open-api/typescript-sdk/fetch-client/models/LogLevel.ts new file mode 100644 index 0000000000..0c4333893d --- /dev/null +++ b/open-api/typescript-sdk/fetch-client/models/LogLevel.ts @@ -0,0 +1,42 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * Immich + * Immich API + * + * The version of the OpenAPI document: 1.94.1 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + + +/** + * + * @export + */ +export const LogLevel = { + Verbose: 'verbose', + Debug: 'debug', + Log: 'log', + Warn: 'warn', + Error: 'error', + Fatal: 'fatal' +} as const; +export type LogLevel = typeof LogLevel[keyof typeof LogLevel]; + + +export function LogLevelFromJSON(json: any): LogLevel { + return LogLevelFromJSONTyped(json, false); +} + +export function LogLevelFromJSONTyped(json: any, ignoreDiscriminator: boolean): LogLevel { + return json as LogLevel; +} + +export function LogLevelToJSON(value?: LogLevel | null): any { + return value as any; +} + diff --git a/open-api/typescript-sdk/fetch-client/models/LoginCredentialDto.ts b/open-api/typescript-sdk/fetch-client/models/LoginCredentialDto.ts new file mode 100644 index 0000000000..2bf85ca350 --- /dev/null +++ b/open-api/typescript-sdk/fetch-client/models/LoginCredentialDto.ts @@ -0,0 +1,75 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * Immich + * Immich API + * + * The version of the OpenAPI document: 1.94.1 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + +import { exists, mapValues } from '../runtime'; +/** + * + * @export + * @interface LoginCredentialDto + */ +export interface LoginCredentialDto { + /** + * + * @type {string} + * @memberof LoginCredentialDto + */ + email: string; + /** + * + * @type {string} + * @memberof LoginCredentialDto + */ + password: string; +} + +/** + * Check if a given object implements the LoginCredentialDto interface. + */ +export function instanceOfLoginCredentialDto(value: object): boolean { + let isInstance = true; + isInstance = isInstance && "email" in value; + isInstance = isInstance && "password" in value; + + return isInstance; +} + +export function LoginCredentialDtoFromJSON(json: any): LoginCredentialDto { + return LoginCredentialDtoFromJSONTyped(json, false); +} + +export function LoginCredentialDtoFromJSONTyped(json: any, ignoreDiscriminator: boolean): LoginCredentialDto { + if ((json === undefined) || (json === null)) { + return json; + } + return { + + 'email': json['email'], + 'password': json['password'], + }; +} + +export function LoginCredentialDtoToJSON(value?: LoginCredentialDto | null): any { + if (value === undefined) { + return undefined; + } + if (value === null) { + return null; + } + return { + + 'email': value.email, + 'password': value.password, + }; +} + diff --git a/open-api/typescript-sdk/fetch-client/models/LoginResponseDto.ts b/open-api/typescript-sdk/fetch-client/models/LoginResponseDto.ts new file mode 100644 index 0000000000..355e57e238 --- /dev/null +++ b/open-api/typescript-sdk/fetch-client/models/LoginResponseDto.ts @@ -0,0 +1,120 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * Immich + * Immich API + * + * The version of the OpenAPI document: 1.94.1 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + +import { exists, mapValues } from '../runtime'; +/** + * + * @export + * @interface LoginResponseDto + */ +export interface LoginResponseDto { + /** + * + * @type {string} + * @memberof LoginResponseDto + */ + accessToken: string; + /** + * + * @type {boolean} + * @memberof LoginResponseDto + */ + isAdmin: boolean; + /** + * + * @type {string} + * @memberof LoginResponseDto + */ + name: string; + /** + * + * @type {string} + * @memberof LoginResponseDto + */ + profileImagePath: string; + /** + * + * @type {boolean} + * @memberof LoginResponseDto + */ + shouldChangePassword: boolean; + /** + * + * @type {string} + * @memberof LoginResponseDto + */ + userEmail: string; + /** + * + * @type {string} + * @memberof LoginResponseDto + */ + userId: string; +} + +/** + * Check if a given object implements the LoginResponseDto interface. + */ +export function instanceOfLoginResponseDto(value: object): boolean { + let isInstance = true; + isInstance = isInstance && "accessToken" in value; + isInstance = isInstance && "isAdmin" in value; + isInstance = isInstance && "name" in value; + isInstance = isInstance && "profileImagePath" in value; + isInstance = isInstance && "shouldChangePassword" in value; + isInstance = isInstance && "userEmail" in value; + isInstance = isInstance && "userId" in value; + + return isInstance; +} + +export function LoginResponseDtoFromJSON(json: any): LoginResponseDto { + return LoginResponseDtoFromJSONTyped(json, false); +} + +export function LoginResponseDtoFromJSONTyped(json: any, ignoreDiscriminator: boolean): LoginResponseDto { + if ((json === undefined) || (json === null)) { + return json; + } + return { + + 'accessToken': json['accessToken'], + 'isAdmin': json['isAdmin'], + 'name': json['name'], + 'profileImagePath': json['profileImagePath'], + 'shouldChangePassword': json['shouldChangePassword'], + 'userEmail': json['userEmail'], + 'userId': json['userId'], + }; +} + +export function LoginResponseDtoToJSON(value?: LoginResponseDto | null): any { + if (value === undefined) { + return undefined; + } + if (value === null) { + return null; + } + return { + + 'accessToken': value.accessToken, + 'isAdmin': value.isAdmin, + 'name': value.name, + 'profileImagePath': value.profileImagePath, + 'shouldChangePassword': value.shouldChangePassword, + 'userEmail': value.userEmail, + 'userId': value.userId, + }; +} + diff --git a/open-api/typescript-sdk/fetch-client/models/LogoutResponseDto.ts b/open-api/typescript-sdk/fetch-client/models/LogoutResponseDto.ts new file mode 100644 index 0000000000..1d854ce928 --- /dev/null +++ b/open-api/typescript-sdk/fetch-client/models/LogoutResponseDto.ts @@ -0,0 +1,75 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * Immich + * Immich API + * + * The version of the OpenAPI document: 1.94.1 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + +import { exists, mapValues } from '../runtime'; +/** + * + * @export + * @interface LogoutResponseDto + */ +export interface LogoutResponseDto { + /** + * + * @type {string} + * @memberof LogoutResponseDto + */ + redirectUri: string; + /** + * + * @type {boolean} + * @memberof LogoutResponseDto + */ + successful: boolean; +} + +/** + * Check if a given object implements the LogoutResponseDto interface. + */ +export function instanceOfLogoutResponseDto(value: object): boolean { + let isInstance = true; + isInstance = isInstance && "redirectUri" in value; + isInstance = isInstance && "successful" in value; + + return isInstance; +} + +export function LogoutResponseDtoFromJSON(json: any): LogoutResponseDto { + return LogoutResponseDtoFromJSONTyped(json, false); +} + +export function LogoutResponseDtoFromJSONTyped(json: any, ignoreDiscriminator: boolean): LogoutResponseDto { + if ((json === undefined) || (json === null)) { + return json; + } + return { + + 'redirectUri': json['redirectUri'], + 'successful': json['successful'], + }; +} + +export function LogoutResponseDtoToJSON(value?: LogoutResponseDto | null): any { + if (value === undefined) { + return undefined; + } + if (value === null) { + return null; + } + return { + + 'redirectUri': value.redirectUri, + 'successful': value.successful, + }; +} + diff --git a/open-api/typescript-sdk/fetch-client/models/MapMarkerResponseDto.ts b/open-api/typescript-sdk/fetch-client/models/MapMarkerResponseDto.ts new file mode 100644 index 0000000000..031adc12be --- /dev/null +++ b/open-api/typescript-sdk/fetch-client/models/MapMarkerResponseDto.ts @@ -0,0 +1,84 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * Immich + * Immich API + * + * The version of the OpenAPI document: 1.94.1 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + +import { exists, mapValues } from '../runtime'; +/** + * + * @export + * @interface MapMarkerResponseDto + */ +export interface MapMarkerResponseDto { + /** + * + * @type {string} + * @memberof MapMarkerResponseDto + */ + id: string; + /** + * + * @type {number} + * @memberof MapMarkerResponseDto + */ + lat: number; + /** + * + * @type {number} + * @memberof MapMarkerResponseDto + */ + lon: number; +} + +/** + * Check if a given object implements the MapMarkerResponseDto interface. + */ +export function instanceOfMapMarkerResponseDto(value: object): boolean { + let isInstance = true; + isInstance = isInstance && "id" in value; + isInstance = isInstance && "lat" in value; + isInstance = isInstance && "lon" in value; + + return isInstance; +} + +export function MapMarkerResponseDtoFromJSON(json: any): MapMarkerResponseDto { + return MapMarkerResponseDtoFromJSONTyped(json, false); +} + +export function MapMarkerResponseDtoFromJSONTyped(json: any, ignoreDiscriminator: boolean): MapMarkerResponseDto { + if ((json === undefined) || (json === null)) { + return json; + } + return { + + 'id': json['id'], + 'lat': json['lat'], + 'lon': json['lon'], + }; +} + +export function MapMarkerResponseDtoToJSON(value?: MapMarkerResponseDto | null): any { + if (value === undefined) { + return undefined; + } + if (value === null) { + return null; + } + return { + + 'id': value.id, + 'lat': value.lat, + 'lon': value.lon, + }; +} + diff --git a/open-api/typescript-sdk/fetch-client/models/MapTheme.ts b/open-api/typescript-sdk/fetch-client/models/MapTheme.ts new file mode 100644 index 0000000000..737b9b4060 --- /dev/null +++ b/open-api/typescript-sdk/fetch-client/models/MapTheme.ts @@ -0,0 +1,38 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * Immich + * Immich API + * + * The version of the OpenAPI document: 1.94.1 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + + +/** + * + * @export + */ +export const MapTheme = { + Light: 'light', + Dark: 'dark' +} as const; +export type MapTheme = typeof MapTheme[keyof typeof MapTheme]; + + +export function MapThemeFromJSON(json: any): MapTheme { + return MapThemeFromJSONTyped(json, false); +} + +export function MapThemeFromJSONTyped(json: any, ignoreDiscriminator: boolean): MapTheme { + return json as MapTheme; +} + +export function MapThemeToJSON(value?: MapTheme | null): any { + return value as any; +} + diff --git a/open-api/typescript-sdk/fetch-client/models/MemoryLaneResponseDto.ts b/open-api/typescript-sdk/fetch-client/models/MemoryLaneResponseDto.ts new file mode 100644 index 0000000000..2898ace78c --- /dev/null +++ b/open-api/typescript-sdk/fetch-client/models/MemoryLaneResponseDto.ts @@ -0,0 +1,82 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * Immich + * Immich API + * + * The version of the OpenAPI document: 1.94.1 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + +import { exists, mapValues } from '../runtime'; +import type { AssetResponseDto } from './AssetResponseDto'; +import { + AssetResponseDtoFromJSON, + AssetResponseDtoFromJSONTyped, + AssetResponseDtoToJSON, +} from './AssetResponseDto'; + +/** + * + * @export + * @interface MemoryLaneResponseDto + */ +export interface MemoryLaneResponseDto { + /** + * + * @type {Array} + * @memberof MemoryLaneResponseDto + */ + assets: Array; + /** + * + * @type {string} + * @memberof MemoryLaneResponseDto + */ + title: string; +} + +/** + * Check if a given object implements the MemoryLaneResponseDto interface. + */ +export function instanceOfMemoryLaneResponseDto(value: object): boolean { + let isInstance = true; + isInstance = isInstance && "assets" in value; + isInstance = isInstance && "title" in value; + + return isInstance; +} + +export function MemoryLaneResponseDtoFromJSON(json: any): MemoryLaneResponseDto { + return MemoryLaneResponseDtoFromJSONTyped(json, false); +} + +export function MemoryLaneResponseDtoFromJSONTyped(json: any, ignoreDiscriminator: boolean): MemoryLaneResponseDto { + if ((json === undefined) || (json === null)) { + return json; + } + return { + + 'assets': ((json['assets'] as Array).map(AssetResponseDtoFromJSON)), + 'title': json['title'], + }; +} + +export function MemoryLaneResponseDtoToJSON(value?: MemoryLaneResponseDto | null): any { + if (value === undefined) { + return undefined; + } + if (value === null) { + return null; + } + return { + + 'assets': ((value.assets as Array).map(AssetResponseDtoToJSON)), + 'title': value.title, + }; +} + diff --git a/open-api/typescript-sdk/fetch-client/models/MergePersonDto.ts b/open-api/typescript-sdk/fetch-client/models/MergePersonDto.ts new file mode 100644 index 0000000000..dbbbcc8729 --- /dev/null +++ b/open-api/typescript-sdk/fetch-client/models/MergePersonDto.ts @@ -0,0 +1,66 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * Immich + * Immich API + * + * The version of the OpenAPI document: 1.94.1 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + +import { exists, mapValues } from '../runtime'; +/** + * + * @export + * @interface MergePersonDto + */ +export interface MergePersonDto { + /** + * + * @type {Array} + * @memberof MergePersonDto + */ + ids: Array; +} + +/** + * Check if a given object implements the MergePersonDto interface. + */ +export function instanceOfMergePersonDto(value: object): boolean { + let isInstance = true; + isInstance = isInstance && "ids" in value; + + return isInstance; +} + +export function MergePersonDtoFromJSON(json: any): MergePersonDto { + return MergePersonDtoFromJSONTyped(json, false); +} + +export function MergePersonDtoFromJSONTyped(json: any, ignoreDiscriminator: boolean): MergePersonDto { + if ((json === undefined) || (json === null)) { + return json; + } + return { + + 'ids': json['ids'], + }; +} + +export function MergePersonDtoToJSON(value?: MergePersonDto | null): any { + if (value === undefined) { + return undefined; + } + if (value === null) { + return null; + } + return { + + 'ids': value.ids, + }; +} + diff --git a/open-api/typescript-sdk/fetch-client/models/ModelType.ts b/open-api/typescript-sdk/fetch-client/models/ModelType.ts new file mode 100644 index 0000000000..6fbc6e55f3 --- /dev/null +++ b/open-api/typescript-sdk/fetch-client/models/ModelType.ts @@ -0,0 +1,38 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * Immich + * Immich API + * + * The version of the OpenAPI document: 1.94.1 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + + +/** + * + * @export + */ +export const ModelType = { + FacialRecognition: 'facial-recognition', + Clip: 'clip' +} as const; +export type ModelType = typeof ModelType[keyof typeof ModelType]; + + +export function ModelTypeFromJSON(json: any): ModelType { + return ModelTypeFromJSONTyped(json, false); +} + +export function ModelTypeFromJSONTyped(json: any, ignoreDiscriminator: boolean): ModelType { + return json as ModelType; +} + +export function ModelTypeToJSON(value?: ModelType | null): any { + return value as any; +} + diff --git a/open-api/typescript-sdk/fetch-client/models/OAuthAuthorizeResponseDto.ts b/open-api/typescript-sdk/fetch-client/models/OAuthAuthorizeResponseDto.ts new file mode 100644 index 0000000000..2e62143f9c --- /dev/null +++ b/open-api/typescript-sdk/fetch-client/models/OAuthAuthorizeResponseDto.ts @@ -0,0 +1,66 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * Immich + * Immich API + * + * The version of the OpenAPI document: 1.94.1 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + +import { exists, mapValues } from '../runtime'; +/** + * + * @export + * @interface OAuthAuthorizeResponseDto + */ +export interface OAuthAuthorizeResponseDto { + /** + * + * @type {string} + * @memberof OAuthAuthorizeResponseDto + */ + url: string; +} + +/** + * Check if a given object implements the OAuthAuthorizeResponseDto interface. + */ +export function instanceOfOAuthAuthorizeResponseDto(value: object): boolean { + let isInstance = true; + isInstance = isInstance && "url" in value; + + return isInstance; +} + +export function OAuthAuthorizeResponseDtoFromJSON(json: any): OAuthAuthorizeResponseDto { + return OAuthAuthorizeResponseDtoFromJSONTyped(json, false); +} + +export function OAuthAuthorizeResponseDtoFromJSONTyped(json: any, ignoreDiscriminator: boolean): OAuthAuthorizeResponseDto { + if ((json === undefined) || (json === null)) { + return json; + } + return { + + 'url': json['url'], + }; +} + +export function OAuthAuthorizeResponseDtoToJSON(value?: OAuthAuthorizeResponseDto | null): any { + if (value === undefined) { + return undefined; + } + if (value === null) { + return null; + } + return { + + 'url': value.url, + }; +} + diff --git a/open-api/typescript-sdk/fetch-client/models/OAuthCallbackDto.ts b/open-api/typescript-sdk/fetch-client/models/OAuthCallbackDto.ts new file mode 100644 index 0000000000..5e119d9f87 --- /dev/null +++ b/open-api/typescript-sdk/fetch-client/models/OAuthCallbackDto.ts @@ -0,0 +1,66 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * Immich + * Immich API + * + * The version of the OpenAPI document: 1.94.1 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + +import { exists, mapValues } from '../runtime'; +/** + * + * @export + * @interface OAuthCallbackDto + */ +export interface OAuthCallbackDto { + /** + * + * @type {string} + * @memberof OAuthCallbackDto + */ + url: string; +} + +/** + * Check if a given object implements the OAuthCallbackDto interface. + */ +export function instanceOfOAuthCallbackDto(value: object): boolean { + let isInstance = true; + isInstance = isInstance && "url" in value; + + return isInstance; +} + +export function OAuthCallbackDtoFromJSON(json: any): OAuthCallbackDto { + return OAuthCallbackDtoFromJSONTyped(json, false); +} + +export function OAuthCallbackDtoFromJSONTyped(json: any, ignoreDiscriminator: boolean): OAuthCallbackDto { + if ((json === undefined) || (json === null)) { + return json; + } + return { + + 'url': json['url'], + }; +} + +export function OAuthCallbackDtoToJSON(value?: OAuthCallbackDto | null): any { + if (value === undefined) { + return undefined; + } + if (value === null) { + return null; + } + return { + + 'url': value.url, + }; +} + diff --git a/open-api/typescript-sdk/fetch-client/models/OAuthConfigDto.ts b/open-api/typescript-sdk/fetch-client/models/OAuthConfigDto.ts new file mode 100644 index 0000000000..c81cb6cb0d --- /dev/null +++ b/open-api/typescript-sdk/fetch-client/models/OAuthConfigDto.ts @@ -0,0 +1,66 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * Immich + * Immich API + * + * The version of the OpenAPI document: 1.94.1 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + +import { exists, mapValues } from '../runtime'; +/** + * + * @export + * @interface OAuthConfigDto + */ +export interface OAuthConfigDto { + /** + * + * @type {string} + * @memberof OAuthConfigDto + */ + redirectUri: string; +} + +/** + * Check if a given object implements the OAuthConfigDto interface. + */ +export function instanceOfOAuthConfigDto(value: object): boolean { + let isInstance = true; + isInstance = isInstance && "redirectUri" in value; + + return isInstance; +} + +export function OAuthConfigDtoFromJSON(json: any): OAuthConfigDto { + return OAuthConfigDtoFromJSONTyped(json, false); +} + +export function OAuthConfigDtoFromJSONTyped(json: any, ignoreDiscriminator: boolean): OAuthConfigDto { + if ((json === undefined) || (json === null)) { + return json; + } + return { + + 'redirectUri': json['redirectUri'], + }; +} + +export function OAuthConfigDtoToJSON(value?: OAuthConfigDto | null): any { + if (value === undefined) { + return undefined; + } + if (value === null) { + return null; + } + return { + + 'redirectUri': value.redirectUri, + }; +} + diff --git a/open-api/typescript-sdk/fetch-client/models/OAuthConfigResponseDto.ts b/open-api/typescript-sdk/fetch-client/models/OAuthConfigResponseDto.ts new file mode 100644 index 0000000000..bb7714b6f8 --- /dev/null +++ b/open-api/typescript-sdk/fetch-client/models/OAuthConfigResponseDto.ts @@ -0,0 +1,99 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * Immich + * Immich API + * + * The version of the OpenAPI document: 1.94.1 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + +import { exists, mapValues } from '../runtime'; +/** + * + * @export + * @interface OAuthConfigResponseDto + */ +export interface OAuthConfigResponseDto { + /** + * + * @type {boolean} + * @memberof OAuthConfigResponseDto + */ + autoLaunch?: boolean; + /** + * + * @type {string} + * @memberof OAuthConfigResponseDto + */ + buttonText?: string; + /** + * + * @type {boolean} + * @memberof OAuthConfigResponseDto + */ + enabled: boolean; + /** + * + * @type {boolean} + * @memberof OAuthConfigResponseDto + */ + passwordLoginEnabled: boolean; + /** + * + * @type {string} + * @memberof OAuthConfigResponseDto + */ + url?: string; +} + +/** + * Check if a given object implements the OAuthConfigResponseDto interface. + */ +export function instanceOfOAuthConfigResponseDto(value: object): boolean { + let isInstance = true; + isInstance = isInstance && "enabled" in value; + isInstance = isInstance && "passwordLoginEnabled" in value; + + return isInstance; +} + +export function OAuthConfigResponseDtoFromJSON(json: any): OAuthConfigResponseDto { + return OAuthConfigResponseDtoFromJSONTyped(json, false); +} + +export function OAuthConfigResponseDtoFromJSONTyped(json: any, ignoreDiscriminator: boolean): OAuthConfigResponseDto { + if ((json === undefined) || (json === null)) { + return json; + } + return { + + 'autoLaunch': !exists(json, 'autoLaunch') ? undefined : json['autoLaunch'], + 'buttonText': !exists(json, 'buttonText') ? undefined : json['buttonText'], + 'enabled': json['enabled'], + 'passwordLoginEnabled': json['passwordLoginEnabled'], + 'url': !exists(json, 'url') ? undefined : json['url'], + }; +} + +export function OAuthConfigResponseDtoToJSON(value?: OAuthConfigResponseDto | null): any { + if (value === undefined) { + return undefined; + } + if (value === null) { + return null; + } + return { + + 'autoLaunch': value.autoLaunch, + 'buttonText': value.buttonText, + 'enabled': value.enabled, + 'passwordLoginEnabled': value.passwordLoginEnabled, + 'url': value.url, + }; +} + diff --git a/open-api/typescript-sdk/fetch-client/models/PartnerResponseDto.ts b/open-api/typescript-sdk/fetch-client/models/PartnerResponseDto.ts new file mode 100644 index 0000000000..646deb4d04 --- /dev/null +++ b/open-api/typescript-sdk/fetch-client/models/PartnerResponseDto.ts @@ -0,0 +1,215 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * Immich + * Immich API + * + * The version of the OpenAPI document: 1.94.1 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + +import { exists, mapValues } from '../runtime'; +import type { UserAvatarColor } from './UserAvatarColor'; +import { + UserAvatarColorFromJSON, + UserAvatarColorFromJSONTyped, + UserAvatarColorToJSON, +} from './UserAvatarColor'; + +/** + * + * @export + * @interface PartnerResponseDto + */ +export interface PartnerResponseDto { + /** + * + * @type {UserAvatarColor} + * @memberof PartnerResponseDto + */ + avatarColor: UserAvatarColor; + /** + * + * @type {Date} + * @memberof PartnerResponseDto + */ + createdAt: Date; + /** + * + * @type {Date} + * @memberof PartnerResponseDto + */ + deletedAt: Date | null; + /** + * + * @type {string} + * @memberof PartnerResponseDto + */ + email: string; + /** + * + * @type {string} + * @memberof PartnerResponseDto + */ + externalPath: string | null; + /** + * + * @type {string} + * @memberof PartnerResponseDto + */ + id: string; + /** + * + * @type {boolean} + * @memberof PartnerResponseDto + */ + inTimeline?: boolean; + /** + * + * @type {boolean} + * @memberof PartnerResponseDto + */ + isAdmin: boolean; + /** + * + * @type {boolean} + * @memberof PartnerResponseDto + */ + memoriesEnabled?: boolean; + /** + * + * @type {string} + * @memberof PartnerResponseDto + */ + name: string; + /** + * + * @type {string} + * @memberof PartnerResponseDto + */ + oauthId: string; + /** + * + * @type {string} + * @memberof PartnerResponseDto + */ + profileImagePath: string; + /** + * + * @type {number} + * @memberof PartnerResponseDto + */ + quotaSizeInBytes: number | null; + /** + * + * @type {number} + * @memberof PartnerResponseDto + */ + quotaUsageInBytes: number | null; + /** + * + * @type {boolean} + * @memberof PartnerResponseDto + */ + shouldChangePassword: boolean; + /** + * + * @type {string} + * @memberof PartnerResponseDto + */ + storageLabel: string | null; + /** + * + * @type {Date} + * @memberof PartnerResponseDto + */ + updatedAt: Date; +} + +/** + * Check if a given object implements the PartnerResponseDto interface. + */ +export function instanceOfPartnerResponseDto(value: object): boolean { + let isInstance = true; + isInstance = isInstance && "avatarColor" in value; + isInstance = isInstance && "createdAt" in value; + isInstance = isInstance && "deletedAt" in value; + isInstance = isInstance && "email" in value; + isInstance = isInstance && "externalPath" in value; + isInstance = isInstance && "id" in value; + isInstance = isInstance && "isAdmin" in value; + isInstance = isInstance && "name" in value; + isInstance = isInstance && "oauthId" in value; + isInstance = isInstance && "profileImagePath" in value; + isInstance = isInstance && "quotaSizeInBytes" in value; + isInstance = isInstance && "quotaUsageInBytes" in value; + isInstance = isInstance && "shouldChangePassword" in value; + isInstance = isInstance && "storageLabel" in value; + isInstance = isInstance && "updatedAt" in value; + + return isInstance; +} + +export function PartnerResponseDtoFromJSON(json: any): PartnerResponseDto { + return PartnerResponseDtoFromJSONTyped(json, false); +} + +export function PartnerResponseDtoFromJSONTyped(json: any, ignoreDiscriminator: boolean): PartnerResponseDto { + if ((json === undefined) || (json === null)) { + return json; + } + return { + + 'avatarColor': UserAvatarColorFromJSON(json['avatarColor']), + 'createdAt': (new Date(json['createdAt'])), + 'deletedAt': (json['deletedAt'] === null ? null : new Date(json['deletedAt'])), + 'email': json['email'], + 'externalPath': json['externalPath'], + 'id': json['id'], + 'inTimeline': !exists(json, 'inTimeline') ? undefined : json['inTimeline'], + 'isAdmin': json['isAdmin'], + 'memoriesEnabled': !exists(json, 'memoriesEnabled') ? undefined : json['memoriesEnabled'], + 'name': json['name'], + 'oauthId': json['oauthId'], + 'profileImagePath': json['profileImagePath'], + 'quotaSizeInBytes': json['quotaSizeInBytes'], + 'quotaUsageInBytes': json['quotaUsageInBytes'], + 'shouldChangePassword': json['shouldChangePassword'], + 'storageLabel': json['storageLabel'], + 'updatedAt': (new Date(json['updatedAt'])), + }; +} + +export function PartnerResponseDtoToJSON(value?: PartnerResponseDto | null): any { + if (value === undefined) { + return undefined; + } + if (value === null) { + return null; + } + return { + + 'avatarColor': UserAvatarColorToJSON(value.avatarColor), + 'createdAt': (value.createdAt.toISOString()), + 'deletedAt': (value.deletedAt === null ? null : value.deletedAt.toISOString()), + 'email': value.email, + 'externalPath': value.externalPath, + 'id': value.id, + 'inTimeline': value.inTimeline, + 'isAdmin': value.isAdmin, + 'memoriesEnabled': value.memoriesEnabled, + 'name': value.name, + 'oauthId': value.oauthId, + 'profileImagePath': value.profileImagePath, + 'quotaSizeInBytes': value.quotaSizeInBytes, + 'quotaUsageInBytes': value.quotaUsageInBytes, + 'shouldChangePassword': value.shouldChangePassword, + 'storageLabel': value.storageLabel, + 'updatedAt': (value.updatedAt.toISOString()), + }; +} + diff --git a/open-api/typescript-sdk/fetch-client/models/PathEntityType.ts b/open-api/typescript-sdk/fetch-client/models/PathEntityType.ts new file mode 100644 index 0000000000..5567f3f514 --- /dev/null +++ b/open-api/typescript-sdk/fetch-client/models/PathEntityType.ts @@ -0,0 +1,39 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * Immich + * Immich API + * + * The version of the OpenAPI document: 1.94.1 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + + +/** + * + * @export + */ +export const PathEntityType = { + Asset: 'asset', + Person: 'person', + User: 'user' +} as const; +export type PathEntityType = typeof PathEntityType[keyof typeof PathEntityType]; + + +export function PathEntityTypeFromJSON(json: any): PathEntityType { + return PathEntityTypeFromJSONTyped(json, false); +} + +export function PathEntityTypeFromJSONTyped(json: any, ignoreDiscriminator: boolean): PathEntityType { + return json as PathEntityType; +} + +export function PathEntityTypeToJSON(value?: PathEntityType | null): any { + return value as any; +} + diff --git a/open-api/typescript-sdk/fetch-client/models/PathType.ts b/open-api/typescript-sdk/fetch-client/models/PathType.ts new file mode 100644 index 0000000000..8a8a41811b --- /dev/null +++ b/open-api/typescript-sdk/fetch-client/models/PathType.ts @@ -0,0 +1,43 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * Immich + * Immich API + * + * The version of the OpenAPI document: 1.94.1 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + + +/** + * + * @export + */ +export const PathType = { + Original: 'original', + JpegThumbnail: 'jpeg_thumbnail', + WebpThumbnail: 'webp_thumbnail', + EncodedVideo: 'encoded_video', + Sidecar: 'sidecar', + Face: 'face', + Profile: 'profile' +} as const; +export type PathType = typeof PathType[keyof typeof PathType]; + + +export function PathTypeFromJSON(json: any): PathType { + return PathTypeFromJSONTyped(json, false); +} + +export function PathTypeFromJSONTyped(json: any, ignoreDiscriminator: boolean): PathType { + return json as PathType; +} + +export function PathTypeToJSON(value?: PathType | null): any { + return value as any; +} + diff --git a/open-api/typescript-sdk/fetch-client/models/PeopleResponseDto.ts b/open-api/typescript-sdk/fetch-client/models/PeopleResponseDto.ts new file mode 100644 index 0000000000..6892308a93 --- /dev/null +++ b/open-api/typescript-sdk/fetch-client/models/PeopleResponseDto.ts @@ -0,0 +1,82 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * Immich + * Immich API + * + * The version of the OpenAPI document: 1.94.1 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + +import { exists, mapValues } from '../runtime'; +import type { PersonResponseDto } from './PersonResponseDto'; +import { + PersonResponseDtoFromJSON, + PersonResponseDtoFromJSONTyped, + PersonResponseDtoToJSON, +} from './PersonResponseDto'; + +/** + * + * @export + * @interface PeopleResponseDto + */ +export interface PeopleResponseDto { + /** + * + * @type {Array} + * @memberof PeopleResponseDto + */ + people: Array; + /** + * + * @type {number} + * @memberof PeopleResponseDto + */ + total: number; +} + +/** + * Check if a given object implements the PeopleResponseDto interface. + */ +export function instanceOfPeopleResponseDto(value: object): boolean { + let isInstance = true; + isInstance = isInstance && "people" in value; + isInstance = isInstance && "total" in value; + + return isInstance; +} + +export function PeopleResponseDtoFromJSON(json: any): PeopleResponseDto { + return PeopleResponseDtoFromJSONTyped(json, false); +} + +export function PeopleResponseDtoFromJSONTyped(json: any, ignoreDiscriminator: boolean): PeopleResponseDto { + if ((json === undefined) || (json === null)) { + return json; + } + return { + + 'people': ((json['people'] as Array).map(PersonResponseDtoFromJSON)), + 'total': json['total'], + }; +} + +export function PeopleResponseDtoToJSON(value?: PeopleResponseDto | null): any { + if (value === undefined) { + return undefined; + } + if (value === null) { + return null; + } + return { + + 'people': ((value.people as Array).map(PersonResponseDtoToJSON)), + 'total': value.total, + }; +} + diff --git a/open-api/typescript-sdk/fetch-client/models/PeopleUpdateDto.ts b/open-api/typescript-sdk/fetch-client/models/PeopleUpdateDto.ts new file mode 100644 index 0000000000..0a3605b59a --- /dev/null +++ b/open-api/typescript-sdk/fetch-client/models/PeopleUpdateDto.ts @@ -0,0 +1,73 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * Immich + * Immich API + * + * The version of the OpenAPI document: 1.94.1 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + +import { exists, mapValues } from '../runtime'; +import type { PeopleUpdateItem } from './PeopleUpdateItem'; +import { + PeopleUpdateItemFromJSON, + PeopleUpdateItemFromJSONTyped, + PeopleUpdateItemToJSON, +} from './PeopleUpdateItem'; + +/** + * + * @export + * @interface PeopleUpdateDto + */ +export interface PeopleUpdateDto { + /** + * + * @type {Array} + * @memberof PeopleUpdateDto + */ + people: Array; +} + +/** + * Check if a given object implements the PeopleUpdateDto interface. + */ +export function instanceOfPeopleUpdateDto(value: object): boolean { + let isInstance = true; + isInstance = isInstance && "people" in value; + + return isInstance; +} + +export function PeopleUpdateDtoFromJSON(json: any): PeopleUpdateDto { + return PeopleUpdateDtoFromJSONTyped(json, false); +} + +export function PeopleUpdateDtoFromJSONTyped(json: any, ignoreDiscriminator: boolean): PeopleUpdateDto { + if ((json === undefined) || (json === null)) { + return json; + } + return { + + 'people': ((json['people'] as Array).map(PeopleUpdateItemFromJSON)), + }; +} + +export function PeopleUpdateDtoToJSON(value?: PeopleUpdateDto | null): any { + if (value === undefined) { + return undefined; + } + if (value === null) { + return null; + } + return { + + 'people': ((value.people as Array).map(PeopleUpdateItemToJSON)), + }; +} + diff --git a/open-api/typescript-sdk/fetch-client/models/PeopleUpdateItem.ts b/open-api/typescript-sdk/fetch-client/models/PeopleUpdateItem.ts new file mode 100644 index 0000000000..5376f9e4bb --- /dev/null +++ b/open-api/typescript-sdk/fetch-client/models/PeopleUpdateItem.ts @@ -0,0 +1,99 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * Immich + * Immich API + * + * The version of the OpenAPI document: 1.94.1 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + +import { exists, mapValues } from '../runtime'; +/** + * + * @export + * @interface PeopleUpdateItem + */ +export interface PeopleUpdateItem { + /** + * Person date of birth. + * Note: the mobile app cannot currently set the birth date to null. + * @type {Date} + * @memberof PeopleUpdateItem + */ + birthDate?: Date | null; + /** + * Asset is used to get the feature face thumbnail. + * @type {string} + * @memberof PeopleUpdateItem + */ + featureFaceAssetId?: string; + /** + * Person id. + * @type {string} + * @memberof PeopleUpdateItem + */ + id: string; + /** + * Person visibility + * @type {boolean} + * @memberof PeopleUpdateItem + */ + isHidden?: boolean; + /** + * Person name. + * @type {string} + * @memberof PeopleUpdateItem + */ + name?: string; +} + +/** + * Check if a given object implements the PeopleUpdateItem interface. + */ +export function instanceOfPeopleUpdateItem(value: object): boolean { + let isInstance = true; + isInstance = isInstance && "id" in value; + + return isInstance; +} + +export function PeopleUpdateItemFromJSON(json: any): PeopleUpdateItem { + return PeopleUpdateItemFromJSONTyped(json, false); +} + +export function PeopleUpdateItemFromJSONTyped(json: any, ignoreDiscriminator: boolean): PeopleUpdateItem { + if ((json === undefined) || (json === null)) { + return json; + } + return { + + 'birthDate': !exists(json, 'birthDate') ? undefined : (json['birthDate'] === null ? null : new Date(json['birthDate'])), + 'featureFaceAssetId': !exists(json, 'featureFaceAssetId') ? undefined : json['featureFaceAssetId'], + 'id': json['id'], + 'isHidden': !exists(json, 'isHidden') ? undefined : json['isHidden'], + 'name': !exists(json, 'name') ? undefined : json['name'], + }; +} + +export function PeopleUpdateItemToJSON(value?: PeopleUpdateItem | null): any { + if (value === undefined) { + return undefined; + } + if (value === null) { + return null; + } + return { + + 'birthDate': value.birthDate === undefined ? undefined : (value.birthDate === null ? null : value.birthDate.toISOString().substring(0,10)), + 'featureFaceAssetId': value.featureFaceAssetId, + 'id': value.id, + 'isHidden': value.isHidden, + 'name': value.name, + }; +} + diff --git a/open-api/typescript-sdk/fetch-client/models/PersonResponseDto.ts b/open-api/typescript-sdk/fetch-client/models/PersonResponseDto.ts new file mode 100644 index 0000000000..ae54ad5676 --- /dev/null +++ b/open-api/typescript-sdk/fetch-client/models/PersonResponseDto.ts @@ -0,0 +1,102 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * Immich + * Immich API + * + * The version of the OpenAPI document: 1.94.1 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + +import { exists, mapValues } from '../runtime'; +/** + * + * @export + * @interface PersonResponseDto + */ +export interface PersonResponseDto { + /** + * + * @type {Date} + * @memberof PersonResponseDto + */ + birthDate: Date | null; + /** + * + * @type {string} + * @memberof PersonResponseDto + */ + id: string; + /** + * + * @type {boolean} + * @memberof PersonResponseDto + */ + isHidden: boolean; + /** + * + * @type {string} + * @memberof PersonResponseDto + */ + name: string; + /** + * + * @type {string} + * @memberof PersonResponseDto + */ + thumbnailPath: string; +} + +/** + * Check if a given object implements the PersonResponseDto interface. + */ +export function instanceOfPersonResponseDto(value: object): boolean { + let isInstance = true; + isInstance = isInstance && "birthDate" in value; + isInstance = isInstance && "id" in value; + isInstance = isInstance && "isHidden" in value; + isInstance = isInstance && "name" in value; + isInstance = isInstance && "thumbnailPath" in value; + + return isInstance; +} + +export function PersonResponseDtoFromJSON(json: any): PersonResponseDto { + return PersonResponseDtoFromJSONTyped(json, false); +} + +export function PersonResponseDtoFromJSONTyped(json: any, ignoreDiscriminator: boolean): PersonResponseDto { + if ((json === undefined) || (json === null)) { + return json; + } + return { + + 'birthDate': (json['birthDate'] === null ? null : new Date(json['birthDate'])), + 'id': json['id'], + 'isHidden': json['isHidden'], + 'name': json['name'], + 'thumbnailPath': json['thumbnailPath'], + }; +} + +export function PersonResponseDtoToJSON(value?: PersonResponseDto | null): any { + if (value === undefined) { + return undefined; + } + if (value === null) { + return null; + } + return { + + 'birthDate': (value.birthDate === null ? null : value.birthDate.toISOString().substring(0,10)), + 'id': value.id, + 'isHidden': value.isHidden, + 'name': value.name, + 'thumbnailPath': value.thumbnailPath, + }; +} + diff --git a/open-api/typescript-sdk/fetch-client/models/PersonStatisticsResponseDto.ts b/open-api/typescript-sdk/fetch-client/models/PersonStatisticsResponseDto.ts new file mode 100644 index 0000000000..8497a95424 --- /dev/null +++ b/open-api/typescript-sdk/fetch-client/models/PersonStatisticsResponseDto.ts @@ -0,0 +1,66 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * Immich + * Immich API + * + * The version of the OpenAPI document: 1.94.1 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + +import { exists, mapValues } from '../runtime'; +/** + * + * @export + * @interface PersonStatisticsResponseDto + */ +export interface PersonStatisticsResponseDto { + /** + * + * @type {number} + * @memberof PersonStatisticsResponseDto + */ + assets: number; +} + +/** + * Check if a given object implements the PersonStatisticsResponseDto interface. + */ +export function instanceOfPersonStatisticsResponseDto(value: object): boolean { + let isInstance = true; + isInstance = isInstance && "assets" in value; + + return isInstance; +} + +export function PersonStatisticsResponseDtoFromJSON(json: any): PersonStatisticsResponseDto { + return PersonStatisticsResponseDtoFromJSONTyped(json, false); +} + +export function PersonStatisticsResponseDtoFromJSONTyped(json: any, ignoreDiscriminator: boolean): PersonStatisticsResponseDto { + if ((json === undefined) || (json === null)) { + return json; + } + return { + + 'assets': json['assets'], + }; +} + +export function PersonStatisticsResponseDtoToJSON(value?: PersonStatisticsResponseDto | null): any { + if (value === undefined) { + return undefined; + } + if (value === null) { + return null; + } + return { + + 'assets': value.assets, + }; +} + diff --git a/open-api/typescript-sdk/fetch-client/models/PersonUpdateDto.ts b/open-api/typescript-sdk/fetch-client/models/PersonUpdateDto.ts new file mode 100644 index 0000000000..a26f0c1658 --- /dev/null +++ b/open-api/typescript-sdk/fetch-client/models/PersonUpdateDto.ts @@ -0,0 +1,90 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * Immich + * Immich API + * + * The version of the OpenAPI document: 1.94.1 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + +import { exists, mapValues } from '../runtime'; +/** + * + * @export + * @interface PersonUpdateDto + */ +export interface PersonUpdateDto { + /** + * Person date of birth. + * Note: the mobile app cannot currently set the birth date to null. + * @type {Date} + * @memberof PersonUpdateDto + */ + birthDate?: Date | null; + /** + * Asset is used to get the feature face thumbnail. + * @type {string} + * @memberof PersonUpdateDto + */ + featureFaceAssetId?: string; + /** + * Person visibility + * @type {boolean} + * @memberof PersonUpdateDto + */ + isHidden?: boolean; + /** + * Person name. + * @type {string} + * @memberof PersonUpdateDto + */ + name?: string; +} + +/** + * Check if a given object implements the PersonUpdateDto interface. + */ +export function instanceOfPersonUpdateDto(value: object): boolean { + let isInstance = true; + + return isInstance; +} + +export function PersonUpdateDtoFromJSON(json: any): PersonUpdateDto { + return PersonUpdateDtoFromJSONTyped(json, false); +} + +export function PersonUpdateDtoFromJSONTyped(json: any, ignoreDiscriminator: boolean): PersonUpdateDto { + if ((json === undefined) || (json === null)) { + return json; + } + return { + + 'birthDate': !exists(json, 'birthDate') ? undefined : (json['birthDate'] === null ? null : new Date(json['birthDate'])), + 'featureFaceAssetId': !exists(json, 'featureFaceAssetId') ? undefined : json['featureFaceAssetId'], + 'isHidden': !exists(json, 'isHidden') ? undefined : json['isHidden'], + 'name': !exists(json, 'name') ? undefined : json['name'], + }; +} + +export function PersonUpdateDtoToJSON(value?: PersonUpdateDto | null): any { + if (value === undefined) { + return undefined; + } + if (value === null) { + return null; + } + return { + + 'birthDate': value.birthDate === undefined ? undefined : (value.birthDate === null ? null : value.birthDate.toISOString().substring(0,10)), + 'featureFaceAssetId': value.featureFaceAssetId, + 'isHidden': value.isHidden, + 'name': value.name, + }; +} + diff --git a/open-api/typescript-sdk/fetch-client/models/PersonWithFacesResponseDto.ts b/open-api/typescript-sdk/fetch-client/models/PersonWithFacesResponseDto.ts new file mode 100644 index 0000000000..cb614f405c --- /dev/null +++ b/open-api/typescript-sdk/fetch-client/models/PersonWithFacesResponseDto.ts @@ -0,0 +1,118 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * Immich + * Immich API + * + * The version of the OpenAPI document: 1.94.1 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + +import { exists, mapValues } from '../runtime'; +import type { AssetFaceWithoutPersonResponseDto } from './AssetFaceWithoutPersonResponseDto'; +import { + AssetFaceWithoutPersonResponseDtoFromJSON, + AssetFaceWithoutPersonResponseDtoFromJSONTyped, + AssetFaceWithoutPersonResponseDtoToJSON, +} from './AssetFaceWithoutPersonResponseDto'; + +/** + * + * @export + * @interface PersonWithFacesResponseDto + */ +export interface PersonWithFacesResponseDto { + /** + * + * @type {Date} + * @memberof PersonWithFacesResponseDto + */ + birthDate: Date | null; + /** + * + * @type {Array} + * @memberof PersonWithFacesResponseDto + */ + faces: Array; + /** + * + * @type {string} + * @memberof PersonWithFacesResponseDto + */ + id: string; + /** + * + * @type {boolean} + * @memberof PersonWithFacesResponseDto + */ + isHidden: boolean; + /** + * + * @type {string} + * @memberof PersonWithFacesResponseDto + */ + name: string; + /** + * + * @type {string} + * @memberof PersonWithFacesResponseDto + */ + thumbnailPath: string; +} + +/** + * Check if a given object implements the PersonWithFacesResponseDto interface. + */ +export function instanceOfPersonWithFacesResponseDto(value: object): boolean { + let isInstance = true; + isInstance = isInstance && "birthDate" in value; + isInstance = isInstance && "faces" in value; + isInstance = isInstance && "id" in value; + isInstance = isInstance && "isHidden" in value; + isInstance = isInstance && "name" in value; + isInstance = isInstance && "thumbnailPath" in value; + + return isInstance; +} + +export function PersonWithFacesResponseDtoFromJSON(json: any): PersonWithFacesResponseDto { + return PersonWithFacesResponseDtoFromJSONTyped(json, false); +} + +export function PersonWithFacesResponseDtoFromJSONTyped(json: any, ignoreDiscriminator: boolean): PersonWithFacesResponseDto { + if ((json === undefined) || (json === null)) { + return json; + } + return { + + 'birthDate': (json['birthDate'] === null ? null : new Date(json['birthDate'])), + 'faces': ((json['faces'] as Array).map(AssetFaceWithoutPersonResponseDtoFromJSON)), + 'id': json['id'], + 'isHidden': json['isHidden'], + 'name': json['name'], + 'thumbnailPath': json['thumbnailPath'], + }; +} + +export function PersonWithFacesResponseDtoToJSON(value?: PersonWithFacesResponseDto | null): any { + if (value === undefined) { + return undefined; + } + if (value === null) { + return null; + } + return { + + 'birthDate': (value.birthDate === null ? null : value.birthDate.toISOString().substring(0,10)), + 'faces': ((value.faces as Array).map(AssetFaceWithoutPersonResponseDtoToJSON)), + 'id': value.id, + 'isHidden': value.isHidden, + 'name': value.name, + 'thumbnailPath': value.thumbnailPath, + }; +} + diff --git a/open-api/typescript-sdk/fetch-client/models/QueueStatusDto.ts b/open-api/typescript-sdk/fetch-client/models/QueueStatusDto.ts new file mode 100644 index 0000000000..4cfa0fc37f --- /dev/null +++ b/open-api/typescript-sdk/fetch-client/models/QueueStatusDto.ts @@ -0,0 +1,75 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * Immich + * Immich API + * + * The version of the OpenAPI document: 1.94.1 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + +import { exists, mapValues } from '../runtime'; +/** + * + * @export + * @interface QueueStatusDto + */ +export interface QueueStatusDto { + /** + * + * @type {boolean} + * @memberof QueueStatusDto + */ + isActive: boolean; + /** + * + * @type {boolean} + * @memberof QueueStatusDto + */ + isPaused: boolean; +} + +/** + * Check if a given object implements the QueueStatusDto interface. + */ +export function instanceOfQueueStatusDto(value: object): boolean { + let isInstance = true; + isInstance = isInstance && "isActive" in value; + isInstance = isInstance && "isPaused" in value; + + return isInstance; +} + +export function QueueStatusDtoFromJSON(json: any): QueueStatusDto { + return QueueStatusDtoFromJSONTyped(json, false); +} + +export function QueueStatusDtoFromJSONTyped(json: any, ignoreDiscriminator: boolean): QueueStatusDto { + if ((json === undefined) || (json === null)) { + return json; + } + return { + + 'isActive': json['isActive'], + 'isPaused': json['isPaused'], + }; +} + +export function QueueStatusDtoToJSON(value?: QueueStatusDto | null): any { + if (value === undefined) { + return undefined; + } + if (value === null) { + return null; + } + return { + + 'isActive': value.isActive, + 'isPaused': value.isPaused, + }; +} + diff --git a/open-api/typescript-sdk/fetch-client/models/ReactionLevel.ts b/open-api/typescript-sdk/fetch-client/models/ReactionLevel.ts new file mode 100644 index 0000000000..df09b8d802 --- /dev/null +++ b/open-api/typescript-sdk/fetch-client/models/ReactionLevel.ts @@ -0,0 +1,38 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * Immich + * Immich API + * + * The version of the OpenAPI document: 1.94.1 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + + +/** + * + * @export + */ +export const ReactionLevel = { + Album: 'album', + Asset: 'asset' +} as const; +export type ReactionLevel = typeof ReactionLevel[keyof typeof ReactionLevel]; + + +export function ReactionLevelFromJSON(json: any): ReactionLevel { + return ReactionLevelFromJSONTyped(json, false); +} + +export function ReactionLevelFromJSONTyped(json: any, ignoreDiscriminator: boolean): ReactionLevel { + return json as ReactionLevel; +} + +export function ReactionLevelToJSON(value?: ReactionLevel | null): any { + return value as any; +} + diff --git a/open-api/typescript-sdk/fetch-client/models/ReactionType.ts b/open-api/typescript-sdk/fetch-client/models/ReactionType.ts new file mode 100644 index 0000000000..5f64ed3180 --- /dev/null +++ b/open-api/typescript-sdk/fetch-client/models/ReactionType.ts @@ -0,0 +1,38 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * Immich + * Immich API + * + * The version of the OpenAPI document: 1.94.1 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + + +/** + * + * @export + */ +export const ReactionType = { + Comment: 'comment', + Like: 'like' +} as const; +export type ReactionType = typeof ReactionType[keyof typeof ReactionType]; + + +export function ReactionTypeFromJSON(json: any): ReactionType { + return ReactionTypeFromJSONTyped(json, false); +} + +export function ReactionTypeFromJSONTyped(json: any, ignoreDiscriminator: boolean): ReactionType { + return json as ReactionType; +} + +export function ReactionTypeToJSON(value?: ReactionType | null): any { + return value as any; +} + diff --git a/open-api/typescript-sdk/fetch-client/models/RecognitionConfig.ts b/open-api/typescript-sdk/fetch-client/models/RecognitionConfig.ts new file mode 100644 index 0000000000..007be641a6 --- /dev/null +++ b/open-api/typescript-sdk/fetch-client/models/RecognitionConfig.ts @@ -0,0 +1,117 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * Immich + * Immich API + * + * The version of the OpenAPI document: 1.94.1 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + +import { exists, mapValues } from '../runtime'; +import type { ModelType } from './ModelType'; +import { + ModelTypeFromJSON, + ModelTypeFromJSONTyped, + ModelTypeToJSON, +} from './ModelType'; + +/** + * + * @export + * @interface RecognitionConfig + */ +export interface RecognitionConfig { + /** + * + * @type {boolean} + * @memberof RecognitionConfig + */ + enabled: boolean; + /** + * + * @type {number} + * @memberof RecognitionConfig + */ + maxDistance: number; + /** + * + * @type {number} + * @memberof RecognitionConfig + */ + minFaces: number; + /** + * + * @type {number} + * @memberof RecognitionConfig + */ + minScore: number; + /** + * + * @type {string} + * @memberof RecognitionConfig + */ + modelName: string; + /** + * + * @type {ModelType} + * @memberof RecognitionConfig + */ + modelType?: ModelType; +} + +/** + * Check if a given object implements the RecognitionConfig interface. + */ +export function instanceOfRecognitionConfig(value: object): boolean { + let isInstance = true; + isInstance = isInstance && "enabled" in value; + isInstance = isInstance && "maxDistance" in value; + isInstance = isInstance && "minFaces" in value; + isInstance = isInstance && "minScore" in value; + isInstance = isInstance && "modelName" in value; + + return isInstance; +} + +export function RecognitionConfigFromJSON(json: any): RecognitionConfig { + return RecognitionConfigFromJSONTyped(json, false); +} + +export function RecognitionConfigFromJSONTyped(json: any, ignoreDiscriminator: boolean): RecognitionConfig { + if ((json === undefined) || (json === null)) { + return json; + } + return { + + 'enabled': json['enabled'], + 'maxDistance': json['maxDistance'], + 'minFaces': json['minFaces'], + 'minScore': json['minScore'], + 'modelName': json['modelName'], + 'modelType': !exists(json, 'modelType') ? undefined : ModelTypeFromJSON(json['modelType']), + }; +} + +export function RecognitionConfigToJSON(value?: RecognitionConfig | null): any { + if (value === undefined) { + return undefined; + } + if (value === null) { + return null; + } + return { + + 'enabled': value.enabled, + 'maxDistance': value.maxDistance, + 'minFaces': value.minFaces, + 'minScore': value.minScore, + 'modelName': value.modelName, + 'modelType': ModelTypeToJSON(value.modelType), + }; +} + diff --git a/open-api/typescript-sdk/fetch-client/models/ScanLibraryDto.ts b/open-api/typescript-sdk/fetch-client/models/ScanLibraryDto.ts new file mode 100644 index 0000000000..683613b806 --- /dev/null +++ b/open-api/typescript-sdk/fetch-client/models/ScanLibraryDto.ts @@ -0,0 +1,73 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * Immich + * Immich API + * + * The version of the OpenAPI document: 1.94.1 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + +import { exists, mapValues } from '../runtime'; +/** + * + * @export + * @interface ScanLibraryDto + */ +export interface ScanLibraryDto { + /** + * + * @type {boolean} + * @memberof ScanLibraryDto + */ + refreshAllFiles?: boolean; + /** + * + * @type {boolean} + * @memberof ScanLibraryDto + */ + refreshModifiedFiles?: boolean; +} + +/** + * Check if a given object implements the ScanLibraryDto interface. + */ +export function instanceOfScanLibraryDto(value: object): boolean { + let isInstance = true; + + return isInstance; +} + +export function ScanLibraryDtoFromJSON(json: any): ScanLibraryDto { + return ScanLibraryDtoFromJSONTyped(json, false); +} + +export function ScanLibraryDtoFromJSONTyped(json: any, ignoreDiscriminator: boolean): ScanLibraryDto { + if ((json === undefined) || (json === null)) { + return json; + } + return { + + 'refreshAllFiles': !exists(json, 'refreshAllFiles') ? undefined : json['refreshAllFiles'], + 'refreshModifiedFiles': !exists(json, 'refreshModifiedFiles') ? undefined : json['refreshModifiedFiles'], + }; +} + +export function ScanLibraryDtoToJSON(value?: ScanLibraryDto | null): any { + if (value === undefined) { + return undefined; + } + if (value === null) { + return null; + } + return { + + 'refreshAllFiles': value.refreshAllFiles, + 'refreshModifiedFiles': value.refreshModifiedFiles, + }; +} + diff --git a/open-api/typescript-sdk/fetch-client/models/SearchAlbumResponseDto.ts b/open-api/typescript-sdk/fetch-client/models/SearchAlbumResponseDto.ts new file mode 100644 index 0000000000..fd20430e2e --- /dev/null +++ b/open-api/typescript-sdk/fetch-client/models/SearchAlbumResponseDto.ts @@ -0,0 +1,106 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * Immich + * Immich API + * + * The version of the OpenAPI document: 1.94.1 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + +import { exists, mapValues } from '../runtime'; +import type { AlbumResponseDto } from './AlbumResponseDto'; +import { + AlbumResponseDtoFromJSON, + AlbumResponseDtoFromJSONTyped, + AlbumResponseDtoToJSON, +} from './AlbumResponseDto'; +import type { SearchFacetResponseDto } from './SearchFacetResponseDto'; +import { + SearchFacetResponseDtoFromJSON, + SearchFacetResponseDtoFromJSONTyped, + SearchFacetResponseDtoToJSON, +} from './SearchFacetResponseDto'; + +/** + * + * @export + * @interface SearchAlbumResponseDto + */ +export interface SearchAlbumResponseDto { + /** + * + * @type {number} + * @memberof SearchAlbumResponseDto + */ + count: number; + /** + * + * @type {Array} + * @memberof SearchAlbumResponseDto + */ + facets: Array; + /** + * + * @type {Array} + * @memberof SearchAlbumResponseDto + */ + items: Array; + /** + * + * @type {number} + * @memberof SearchAlbumResponseDto + */ + total: number; +} + +/** + * Check if a given object implements the SearchAlbumResponseDto interface. + */ +export function instanceOfSearchAlbumResponseDto(value: object): boolean { + let isInstance = true; + isInstance = isInstance && "count" in value; + isInstance = isInstance && "facets" in value; + isInstance = isInstance && "items" in value; + isInstance = isInstance && "total" in value; + + return isInstance; +} + +export function SearchAlbumResponseDtoFromJSON(json: any): SearchAlbumResponseDto { + return SearchAlbumResponseDtoFromJSONTyped(json, false); +} + +export function SearchAlbumResponseDtoFromJSONTyped(json: any, ignoreDiscriminator: boolean): SearchAlbumResponseDto { + if ((json === undefined) || (json === null)) { + return json; + } + return { + + 'count': json['count'], + 'facets': ((json['facets'] as Array).map(SearchFacetResponseDtoFromJSON)), + 'items': ((json['items'] as Array).map(AlbumResponseDtoFromJSON)), + 'total': json['total'], + }; +} + +export function SearchAlbumResponseDtoToJSON(value?: SearchAlbumResponseDto | null): any { + if (value === undefined) { + return undefined; + } + if (value === null) { + return null; + } + return { + + 'count': value.count, + 'facets': ((value.facets as Array).map(SearchFacetResponseDtoToJSON)), + 'items': ((value.items as Array).map(AlbumResponseDtoToJSON)), + 'total': value.total, + }; +} + diff --git a/open-api/typescript-sdk/fetch-client/models/SearchAssetResponseDto.ts b/open-api/typescript-sdk/fetch-client/models/SearchAssetResponseDto.ts new file mode 100644 index 0000000000..e55d720273 --- /dev/null +++ b/open-api/typescript-sdk/fetch-client/models/SearchAssetResponseDto.ts @@ -0,0 +1,106 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * Immich + * Immich API + * + * The version of the OpenAPI document: 1.94.1 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + +import { exists, mapValues } from '../runtime'; +import type { AssetResponseDto } from './AssetResponseDto'; +import { + AssetResponseDtoFromJSON, + AssetResponseDtoFromJSONTyped, + AssetResponseDtoToJSON, +} from './AssetResponseDto'; +import type { SearchFacetResponseDto } from './SearchFacetResponseDto'; +import { + SearchFacetResponseDtoFromJSON, + SearchFacetResponseDtoFromJSONTyped, + SearchFacetResponseDtoToJSON, +} from './SearchFacetResponseDto'; + +/** + * + * @export + * @interface SearchAssetResponseDto + */ +export interface SearchAssetResponseDto { + /** + * + * @type {number} + * @memberof SearchAssetResponseDto + */ + count: number; + /** + * + * @type {Array} + * @memberof SearchAssetResponseDto + */ + facets: Array; + /** + * + * @type {Array} + * @memberof SearchAssetResponseDto + */ + items: Array; + /** + * + * @type {number} + * @memberof SearchAssetResponseDto + */ + total: number; +} + +/** + * Check if a given object implements the SearchAssetResponseDto interface. + */ +export function instanceOfSearchAssetResponseDto(value: object): boolean { + let isInstance = true; + isInstance = isInstance && "count" in value; + isInstance = isInstance && "facets" in value; + isInstance = isInstance && "items" in value; + isInstance = isInstance && "total" in value; + + return isInstance; +} + +export function SearchAssetResponseDtoFromJSON(json: any): SearchAssetResponseDto { + return SearchAssetResponseDtoFromJSONTyped(json, false); +} + +export function SearchAssetResponseDtoFromJSONTyped(json: any, ignoreDiscriminator: boolean): SearchAssetResponseDto { + if ((json === undefined) || (json === null)) { + return json; + } + return { + + 'count': json['count'], + 'facets': ((json['facets'] as Array).map(SearchFacetResponseDtoFromJSON)), + 'items': ((json['items'] as Array).map(AssetResponseDtoFromJSON)), + 'total': json['total'], + }; +} + +export function SearchAssetResponseDtoToJSON(value?: SearchAssetResponseDto | null): any { + if (value === undefined) { + return undefined; + } + if (value === null) { + return null; + } + return { + + 'count': value.count, + 'facets': ((value.facets as Array).map(SearchFacetResponseDtoToJSON)), + 'items': ((value.items as Array).map(AssetResponseDtoToJSON)), + 'total': value.total, + }; +} + diff --git a/open-api/typescript-sdk/fetch-client/models/SearchExploreItem.ts b/open-api/typescript-sdk/fetch-client/models/SearchExploreItem.ts new file mode 100644 index 0000000000..3da965014b --- /dev/null +++ b/open-api/typescript-sdk/fetch-client/models/SearchExploreItem.ts @@ -0,0 +1,82 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * Immich + * Immich API + * + * The version of the OpenAPI document: 1.94.1 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + +import { exists, mapValues } from '../runtime'; +import type { AssetResponseDto } from './AssetResponseDto'; +import { + AssetResponseDtoFromJSON, + AssetResponseDtoFromJSONTyped, + AssetResponseDtoToJSON, +} from './AssetResponseDto'; + +/** + * + * @export + * @interface SearchExploreItem + */ +export interface SearchExploreItem { + /** + * + * @type {AssetResponseDto} + * @memberof SearchExploreItem + */ + data: AssetResponseDto; + /** + * + * @type {string} + * @memberof SearchExploreItem + */ + value: string; +} + +/** + * Check if a given object implements the SearchExploreItem interface. + */ +export function instanceOfSearchExploreItem(value: object): boolean { + let isInstance = true; + isInstance = isInstance && "data" in value; + isInstance = isInstance && "value" in value; + + return isInstance; +} + +export function SearchExploreItemFromJSON(json: any): SearchExploreItem { + return SearchExploreItemFromJSONTyped(json, false); +} + +export function SearchExploreItemFromJSONTyped(json: any, ignoreDiscriminator: boolean): SearchExploreItem { + if ((json === undefined) || (json === null)) { + return json; + } + return { + + 'data': AssetResponseDtoFromJSON(json['data']), + 'value': json['value'], + }; +} + +export function SearchExploreItemToJSON(value?: SearchExploreItem | null): any { + if (value === undefined) { + return undefined; + } + if (value === null) { + return null; + } + return { + + 'data': AssetResponseDtoToJSON(value.data), + 'value': value.value, + }; +} + diff --git a/open-api/typescript-sdk/fetch-client/models/SearchExploreResponseDto.ts b/open-api/typescript-sdk/fetch-client/models/SearchExploreResponseDto.ts new file mode 100644 index 0000000000..d2671e02fe --- /dev/null +++ b/open-api/typescript-sdk/fetch-client/models/SearchExploreResponseDto.ts @@ -0,0 +1,82 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * Immich + * Immich API + * + * The version of the OpenAPI document: 1.94.1 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + +import { exists, mapValues } from '../runtime'; +import type { SearchExploreItem } from './SearchExploreItem'; +import { + SearchExploreItemFromJSON, + SearchExploreItemFromJSONTyped, + SearchExploreItemToJSON, +} from './SearchExploreItem'; + +/** + * + * @export + * @interface SearchExploreResponseDto + */ +export interface SearchExploreResponseDto { + /** + * + * @type {string} + * @memberof SearchExploreResponseDto + */ + fieldName: string; + /** + * + * @type {Array} + * @memberof SearchExploreResponseDto + */ + items: Array; +} + +/** + * Check if a given object implements the SearchExploreResponseDto interface. + */ +export function instanceOfSearchExploreResponseDto(value: object): boolean { + let isInstance = true; + isInstance = isInstance && "fieldName" in value; + isInstance = isInstance && "items" in value; + + return isInstance; +} + +export function SearchExploreResponseDtoFromJSON(json: any): SearchExploreResponseDto { + return SearchExploreResponseDtoFromJSONTyped(json, false); +} + +export function SearchExploreResponseDtoFromJSONTyped(json: any, ignoreDiscriminator: boolean): SearchExploreResponseDto { + if ((json === undefined) || (json === null)) { + return json; + } + return { + + 'fieldName': json['fieldName'], + 'items': ((json['items'] as Array).map(SearchExploreItemFromJSON)), + }; +} + +export function SearchExploreResponseDtoToJSON(value?: SearchExploreResponseDto | null): any { + if (value === undefined) { + return undefined; + } + if (value === null) { + return null; + } + return { + + 'fieldName': value.fieldName, + 'items': ((value.items as Array).map(SearchExploreItemToJSON)), + }; +} + diff --git a/open-api/typescript-sdk/fetch-client/models/SearchFacetCountResponseDto.ts b/open-api/typescript-sdk/fetch-client/models/SearchFacetCountResponseDto.ts new file mode 100644 index 0000000000..e18fa3d84d --- /dev/null +++ b/open-api/typescript-sdk/fetch-client/models/SearchFacetCountResponseDto.ts @@ -0,0 +1,75 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * Immich + * Immich API + * + * The version of the OpenAPI document: 1.94.1 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + +import { exists, mapValues } from '../runtime'; +/** + * + * @export + * @interface SearchFacetCountResponseDto + */ +export interface SearchFacetCountResponseDto { + /** + * + * @type {number} + * @memberof SearchFacetCountResponseDto + */ + count: number; + /** + * + * @type {string} + * @memberof SearchFacetCountResponseDto + */ + value: string; +} + +/** + * Check if a given object implements the SearchFacetCountResponseDto interface. + */ +export function instanceOfSearchFacetCountResponseDto(value: object): boolean { + let isInstance = true; + isInstance = isInstance && "count" in value; + isInstance = isInstance && "value" in value; + + return isInstance; +} + +export function SearchFacetCountResponseDtoFromJSON(json: any): SearchFacetCountResponseDto { + return SearchFacetCountResponseDtoFromJSONTyped(json, false); +} + +export function SearchFacetCountResponseDtoFromJSONTyped(json: any, ignoreDiscriminator: boolean): SearchFacetCountResponseDto { + if ((json === undefined) || (json === null)) { + return json; + } + return { + + 'count': json['count'], + 'value': json['value'], + }; +} + +export function SearchFacetCountResponseDtoToJSON(value?: SearchFacetCountResponseDto | null): any { + if (value === undefined) { + return undefined; + } + if (value === null) { + return null; + } + return { + + 'count': value.count, + 'value': value.value, + }; +} + diff --git a/open-api/typescript-sdk/fetch-client/models/SearchFacetResponseDto.ts b/open-api/typescript-sdk/fetch-client/models/SearchFacetResponseDto.ts new file mode 100644 index 0000000000..14b41751ab --- /dev/null +++ b/open-api/typescript-sdk/fetch-client/models/SearchFacetResponseDto.ts @@ -0,0 +1,82 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * Immich + * Immich API + * + * The version of the OpenAPI document: 1.94.1 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + +import { exists, mapValues } from '../runtime'; +import type { SearchFacetCountResponseDto } from './SearchFacetCountResponseDto'; +import { + SearchFacetCountResponseDtoFromJSON, + SearchFacetCountResponseDtoFromJSONTyped, + SearchFacetCountResponseDtoToJSON, +} from './SearchFacetCountResponseDto'; + +/** + * + * @export + * @interface SearchFacetResponseDto + */ +export interface SearchFacetResponseDto { + /** + * + * @type {Array} + * @memberof SearchFacetResponseDto + */ + counts: Array; + /** + * + * @type {string} + * @memberof SearchFacetResponseDto + */ + fieldName: string; +} + +/** + * Check if a given object implements the SearchFacetResponseDto interface. + */ +export function instanceOfSearchFacetResponseDto(value: object): boolean { + let isInstance = true; + isInstance = isInstance && "counts" in value; + isInstance = isInstance && "fieldName" in value; + + return isInstance; +} + +export function SearchFacetResponseDtoFromJSON(json: any): SearchFacetResponseDto { + return SearchFacetResponseDtoFromJSONTyped(json, false); +} + +export function SearchFacetResponseDtoFromJSONTyped(json: any, ignoreDiscriminator: boolean): SearchFacetResponseDto { + if ((json === undefined) || (json === null)) { + return json; + } + return { + + 'counts': ((json['counts'] as Array).map(SearchFacetCountResponseDtoFromJSON)), + 'fieldName': json['fieldName'], + }; +} + +export function SearchFacetResponseDtoToJSON(value?: SearchFacetResponseDto | null): any { + if (value === undefined) { + return undefined; + } + if (value === null) { + return null; + } + return { + + 'counts': ((value.counts as Array).map(SearchFacetCountResponseDtoToJSON)), + 'fieldName': value.fieldName, + }; +} + diff --git a/open-api/typescript-sdk/fetch-client/models/SearchResponseDto.ts b/open-api/typescript-sdk/fetch-client/models/SearchResponseDto.ts new file mode 100644 index 0000000000..89fa47062f --- /dev/null +++ b/open-api/typescript-sdk/fetch-client/models/SearchResponseDto.ts @@ -0,0 +1,88 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * Immich + * Immich API + * + * The version of the OpenAPI document: 1.94.1 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + +import { exists, mapValues } from '../runtime'; +import type { SearchAlbumResponseDto } from './SearchAlbumResponseDto'; +import { + SearchAlbumResponseDtoFromJSON, + SearchAlbumResponseDtoFromJSONTyped, + SearchAlbumResponseDtoToJSON, +} from './SearchAlbumResponseDto'; +import type { SearchAssetResponseDto } from './SearchAssetResponseDto'; +import { + SearchAssetResponseDtoFromJSON, + SearchAssetResponseDtoFromJSONTyped, + SearchAssetResponseDtoToJSON, +} from './SearchAssetResponseDto'; + +/** + * + * @export + * @interface SearchResponseDto + */ +export interface SearchResponseDto { + /** + * + * @type {SearchAlbumResponseDto} + * @memberof SearchResponseDto + */ + albums: SearchAlbumResponseDto; + /** + * + * @type {SearchAssetResponseDto} + * @memberof SearchResponseDto + */ + assets: SearchAssetResponseDto; +} + +/** + * Check if a given object implements the SearchResponseDto interface. + */ +export function instanceOfSearchResponseDto(value: object): boolean { + let isInstance = true; + isInstance = isInstance && "albums" in value; + isInstance = isInstance && "assets" in value; + + return isInstance; +} + +export function SearchResponseDtoFromJSON(json: any): SearchResponseDto { + return SearchResponseDtoFromJSONTyped(json, false); +} + +export function SearchResponseDtoFromJSONTyped(json: any, ignoreDiscriminator: boolean): SearchResponseDto { + if ((json === undefined) || (json === null)) { + return json; + } + return { + + 'albums': SearchAlbumResponseDtoFromJSON(json['albums']), + 'assets': SearchAssetResponseDtoFromJSON(json['assets']), + }; +} + +export function SearchResponseDtoToJSON(value?: SearchResponseDto | null): any { + if (value === undefined) { + return undefined; + } + if (value === null) { + return null; + } + return { + + 'albums': SearchAlbumResponseDtoToJSON(value.albums), + 'assets': SearchAssetResponseDtoToJSON(value.assets), + }; +} + diff --git a/open-api/typescript-sdk/fetch-client/models/ServerConfigDto.ts b/open-api/typescript-sdk/fetch-client/models/ServerConfigDto.ts new file mode 100644 index 0000000000..4db3fd3536 --- /dev/null +++ b/open-api/typescript-sdk/fetch-client/models/ServerConfigDto.ts @@ -0,0 +1,111 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * Immich + * Immich API + * + * The version of the OpenAPI document: 1.94.1 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + +import { exists, mapValues } from '../runtime'; +/** + * + * @export + * @interface ServerConfigDto + */ +export interface ServerConfigDto { + /** + * + * @type {string} + * @memberof ServerConfigDto + */ + externalDomain: string; + /** + * + * @type {boolean} + * @memberof ServerConfigDto + */ + isInitialized: boolean; + /** + * + * @type {boolean} + * @memberof ServerConfigDto + */ + isOnboarded: boolean; + /** + * + * @type {string} + * @memberof ServerConfigDto + */ + loginPageMessage: string; + /** + * + * @type {string} + * @memberof ServerConfigDto + */ + oauthButtonText: string; + /** + * + * @type {number} + * @memberof ServerConfigDto + */ + trashDays: number; +} + +/** + * Check if a given object implements the ServerConfigDto interface. + */ +export function instanceOfServerConfigDto(value: object): boolean { + let isInstance = true; + isInstance = isInstance && "externalDomain" in value; + isInstance = isInstance && "isInitialized" in value; + isInstance = isInstance && "isOnboarded" in value; + isInstance = isInstance && "loginPageMessage" in value; + isInstance = isInstance && "oauthButtonText" in value; + isInstance = isInstance && "trashDays" in value; + + return isInstance; +} + +export function ServerConfigDtoFromJSON(json: any): ServerConfigDto { + return ServerConfigDtoFromJSONTyped(json, false); +} + +export function ServerConfigDtoFromJSONTyped(json: any, ignoreDiscriminator: boolean): ServerConfigDto { + if ((json === undefined) || (json === null)) { + return json; + } + return { + + 'externalDomain': json['externalDomain'], + 'isInitialized': json['isInitialized'], + 'isOnboarded': json['isOnboarded'], + 'loginPageMessage': json['loginPageMessage'], + 'oauthButtonText': json['oauthButtonText'], + 'trashDays': json['trashDays'], + }; +} + +export function ServerConfigDtoToJSON(value?: ServerConfigDto | null): any { + if (value === undefined) { + return undefined; + } + if (value === null) { + return null; + } + return { + + 'externalDomain': value.externalDomain, + 'isInitialized': value.isInitialized, + 'isOnboarded': value.isOnboarded, + 'loginPageMessage': value.loginPageMessage, + 'oauthButtonText': value.oauthButtonText, + 'trashDays': value.trashDays, + }; +} + diff --git a/open-api/typescript-sdk/fetch-client/models/ServerFeaturesDto.ts b/open-api/typescript-sdk/fetch-client/models/ServerFeaturesDto.ts new file mode 100644 index 0000000000..8c127dce76 --- /dev/null +++ b/open-api/typescript-sdk/fetch-client/models/ServerFeaturesDto.ts @@ -0,0 +1,156 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * Immich + * Immich API + * + * The version of the OpenAPI document: 1.94.1 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + +import { exists, mapValues } from '../runtime'; +/** + * + * @export + * @interface ServerFeaturesDto + */ +export interface ServerFeaturesDto { + /** + * + * @type {boolean} + * @memberof ServerFeaturesDto + */ + configFile: boolean; + /** + * + * @type {boolean} + * @memberof ServerFeaturesDto + */ + facialRecognition: boolean; + /** + * + * @type {boolean} + * @memberof ServerFeaturesDto + */ + map: boolean; + /** + * + * @type {boolean} + * @memberof ServerFeaturesDto + */ + oauth: boolean; + /** + * + * @type {boolean} + * @memberof ServerFeaturesDto + */ + oauthAutoLaunch: boolean; + /** + * + * @type {boolean} + * @memberof ServerFeaturesDto + */ + passwordLogin: boolean; + /** + * + * @type {boolean} + * @memberof ServerFeaturesDto + */ + reverseGeocoding: boolean; + /** + * + * @type {boolean} + * @memberof ServerFeaturesDto + */ + search: boolean; + /** + * + * @type {boolean} + * @memberof ServerFeaturesDto + */ + sidecar: boolean; + /** + * + * @type {boolean} + * @memberof ServerFeaturesDto + */ + smartSearch: boolean; + /** + * + * @type {boolean} + * @memberof ServerFeaturesDto + */ + trash: boolean; +} + +/** + * Check if a given object implements the ServerFeaturesDto interface. + */ +export function instanceOfServerFeaturesDto(value: object): boolean { + let isInstance = true; + isInstance = isInstance && "configFile" in value; + isInstance = isInstance && "facialRecognition" in value; + isInstance = isInstance && "map" in value; + isInstance = isInstance && "oauth" in value; + isInstance = isInstance && "oauthAutoLaunch" in value; + isInstance = isInstance && "passwordLogin" in value; + isInstance = isInstance && "reverseGeocoding" in value; + isInstance = isInstance && "search" in value; + isInstance = isInstance && "sidecar" in value; + isInstance = isInstance && "smartSearch" in value; + isInstance = isInstance && "trash" in value; + + return isInstance; +} + +export function ServerFeaturesDtoFromJSON(json: any): ServerFeaturesDto { + return ServerFeaturesDtoFromJSONTyped(json, false); +} + +export function ServerFeaturesDtoFromJSONTyped(json: any, ignoreDiscriminator: boolean): ServerFeaturesDto { + if ((json === undefined) || (json === null)) { + return json; + } + return { + + 'configFile': json['configFile'], + 'facialRecognition': json['facialRecognition'], + 'map': json['map'], + 'oauth': json['oauth'], + 'oauthAutoLaunch': json['oauthAutoLaunch'], + 'passwordLogin': json['passwordLogin'], + 'reverseGeocoding': json['reverseGeocoding'], + 'search': json['search'], + 'sidecar': json['sidecar'], + 'smartSearch': json['smartSearch'], + 'trash': json['trash'], + }; +} + +export function ServerFeaturesDtoToJSON(value?: ServerFeaturesDto | null): any { + if (value === undefined) { + return undefined; + } + if (value === null) { + return null; + } + return { + + 'configFile': value.configFile, + 'facialRecognition': value.facialRecognition, + 'map': value.map, + 'oauth': value.oauth, + 'oauthAutoLaunch': value.oauthAutoLaunch, + 'passwordLogin': value.passwordLogin, + 'reverseGeocoding': value.reverseGeocoding, + 'search': value.search, + 'sidecar': value.sidecar, + 'smartSearch': value.smartSearch, + 'trash': value.trash, + }; +} + diff --git a/open-api/typescript-sdk/fetch-client/models/ServerInfoResponseDto.ts b/open-api/typescript-sdk/fetch-client/models/ServerInfoResponseDto.ts new file mode 100644 index 0000000000..fd1a94eaf4 --- /dev/null +++ b/open-api/typescript-sdk/fetch-client/models/ServerInfoResponseDto.ts @@ -0,0 +1,120 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * Immich + * Immich API + * + * The version of the OpenAPI document: 1.94.1 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + +import { exists, mapValues } from '../runtime'; +/** + * + * @export + * @interface ServerInfoResponseDto + */ +export interface ServerInfoResponseDto { + /** + * + * @type {string} + * @memberof ServerInfoResponseDto + */ + diskAvailable: string; + /** + * + * @type {number} + * @memberof ServerInfoResponseDto + */ + diskAvailableRaw: number; + /** + * + * @type {string} + * @memberof ServerInfoResponseDto + */ + diskSize: string; + /** + * + * @type {number} + * @memberof ServerInfoResponseDto + */ + diskSizeRaw: number; + /** + * + * @type {number} + * @memberof ServerInfoResponseDto + */ + diskUsagePercentage: number; + /** + * + * @type {string} + * @memberof ServerInfoResponseDto + */ + diskUse: string; + /** + * + * @type {number} + * @memberof ServerInfoResponseDto + */ + diskUseRaw: number; +} + +/** + * Check if a given object implements the ServerInfoResponseDto interface. + */ +export function instanceOfServerInfoResponseDto(value: object): boolean { + let isInstance = true; + isInstance = isInstance && "diskAvailable" in value; + isInstance = isInstance && "diskAvailableRaw" in value; + isInstance = isInstance && "diskSize" in value; + isInstance = isInstance && "diskSizeRaw" in value; + isInstance = isInstance && "diskUsagePercentage" in value; + isInstance = isInstance && "diskUse" in value; + isInstance = isInstance && "diskUseRaw" in value; + + return isInstance; +} + +export function ServerInfoResponseDtoFromJSON(json: any): ServerInfoResponseDto { + return ServerInfoResponseDtoFromJSONTyped(json, false); +} + +export function ServerInfoResponseDtoFromJSONTyped(json: any, ignoreDiscriminator: boolean): ServerInfoResponseDto { + if ((json === undefined) || (json === null)) { + return json; + } + return { + + 'diskAvailable': json['diskAvailable'], + 'diskAvailableRaw': json['diskAvailableRaw'], + 'diskSize': json['diskSize'], + 'diskSizeRaw': json['diskSizeRaw'], + 'diskUsagePercentage': json['diskUsagePercentage'], + 'diskUse': json['diskUse'], + 'diskUseRaw': json['diskUseRaw'], + }; +} + +export function ServerInfoResponseDtoToJSON(value?: ServerInfoResponseDto | null): any { + if (value === undefined) { + return undefined; + } + if (value === null) { + return null; + } + return { + + 'diskAvailable': value.diskAvailable, + 'diskAvailableRaw': value.diskAvailableRaw, + 'diskSize': value.diskSize, + 'diskSizeRaw': value.diskSizeRaw, + 'diskUsagePercentage': value.diskUsagePercentage, + 'diskUse': value.diskUse, + 'diskUseRaw': value.diskUseRaw, + }; +} + diff --git a/open-api/typescript-sdk/fetch-client/models/ServerMediaTypesResponseDto.ts b/open-api/typescript-sdk/fetch-client/models/ServerMediaTypesResponseDto.ts new file mode 100644 index 0000000000..9503801818 --- /dev/null +++ b/open-api/typescript-sdk/fetch-client/models/ServerMediaTypesResponseDto.ts @@ -0,0 +1,84 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * Immich + * Immich API + * + * The version of the OpenAPI document: 1.94.1 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + +import { exists, mapValues } from '../runtime'; +/** + * + * @export + * @interface ServerMediaTypesResponseDto + */ +export interface ServerMediaTypesResponseDto { + /** + * + * @type {Array} + * @memberof ServerMediaTypesResponseDto + */ + image: Array; + /** + * + * @type {Array} + * @memberof ServerMediaTypesResponseDto + */ + sidecar: Array; + /** + * + * @type {Array} + * @memberof ServerMediaTypesResponseDto + */ + video: Array; +} + +/** + * Check if a given object implements the ServerMediaTypesResponseDto interface. + */ +export function instanceOfServerMediaTypesResponseDto(value: object): boolean { + let isInstance = true; + isInstance = isInstance && "image" in value; + isInstance = isInstance && "sidecar" in value; + isInstance = isInstance && "video" in value; + + return isInstance; +} + +export function ServerMediaTypesResponseDtoFromJSON(json: any): ServerMediaTypesResponseDto { + return ServerMediaTypesResponseDtoFromJSONTyped(json, false); +} + +export function ServerMediaTypesResponseDtoFromJSONTyped(json: any, ignoreDiscriminator: boolean): ServerMediaTypesResponseDto { + if ((json === undefined) || (json === null)) { + return json; + } + return { + + 'image': json['image'], + 'sidecar': json['sidecar'], + 'video': json['video'], + }; +} + +export function ServerMediaTypesResponseDtoToJSON(value?: ServerMediaTypesResponseDto | null): any { + if (value === undefined) { + return undefined; + } + if (value === null) { + return null; + } + return { + + 'image': value.image, + 'sidecar': value.sidecar, + 'video': value.video, + }; +} + diff --git a/open-api/typescript-sdk/fetch-client/models/ServerPingResponse.ts b/open-api/typescript-sdk/fetch-client/models/ServerPingResponse.ts new file mode 100644 index 0000000000..1ab7605639 --- /dev/null +++ b/open-api/typescript-sdk/fetch-client/models/ServerPingResponse.ts @@ -0,0 +1,65 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * Immich + * Immich API + * + * The version of the OpenAPI document: 1.94.1 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + +import { exists, mapValues } from '../runtime'; +/** + * + * @export + * @interface ServerPingResponse + */ +export interface ServerPingResponse { + /** + * + * @type {string} + * @memberof ServerPingResponse + */ + readonly res: string; +} + +/** + * Check if a given object implements the ServerPingResponse interface. + */ +export function instanceOfServerPingResponse(value: object): boolean { + let isInstance = true; + isInstance = isInstance && "res" in value; + + return isInstance; +} + +export function ServerPingResponseFromJSON(json: any): ServerPingResponse { + return ServerPingResponseFromJSONTyped(json, false); +} + +export function ServerPingResponseFromJSONTyped(json: any, ignoreDiscriminator: boolean): ServerPingResponse { + if ((json === undefined) || (json === null)) { + return json; + } + return { + + 'res': json['res'], + }; +} + +export function ServerPingResponseToJSON(value?: ServerPingResponse | null): any { + if (value === undefined) { + return undefined; + } + if (value === null) { + return null; + } + return { + + }; +} + diff --git a/open-api/typescript-sdk/fetch-client/models/ServerStatsResponseDto.ts b/open-api/typescript-sdk/fetch-client/models/ServerStatsResponseDto.ts new file mode 100644 index 0000000000..10867eec5a --- /dev/null +++ b/open-api/typescript-sdk/fetch-client/models/ServerStatsResponseDto.ts @@ -0,0 +1,100 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * Immich + * Immich API + * + * The version of the OpenAPI document: 1.94.1 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + +import { exists, mapValues } from '../runtime'; +import type { UsageByUserDto } from './UsageByUserDto'; +import { + UsageByUserDtoFromJSON, + UsageByUserDtoFromJSONTyped, + UsageByUserDtoToJSON, +} from './UsageByUserDto'; + +/** + * + * @export + * @interface ServerStatsResponseDto + */ +export interface ServerStatsResponseDto { + /** + * + * @type {number} + * @memberof ServerStatsResponseDto + */ + photos: number; + /** + * + * @type {number} + * @memberof ServerStatsResponseDto + */ + usage: number; + /** + * + * @type {Array} + * @memberof ServerStatsResponseDto + */ + usageByUser: Array; + /** + * + * @type {number} + * @memberof ServerStatsResponseDto + */ + videos: number; +} + +/** + * Check if a given object implements the ServerStatsResponseDto interface. + */ +export function instanceOfServerStatsResponseDto(value: object): boolean { + let isInstance = true; + isInstance = isInstance && "photos" in value; + isInstance = isInstance && "usage" in value; + isInstance = isInstance && "usageByUser" in value; + isInstance = isInstance && "videos" in value; + + return isInstance; +} + +export function ServerStatsResponseDtoFromJSON(json: any): ServerStatsResponseDto { + return ServerStatsResponseDtoFromJSONTyped(json, false); +} + +export function ServerStatsResponseDtoFromJSONTyped(json: any, ignoreDiscriminator: boolean): ServerStatsResponseDto { + if ((json === undefined) || (json === null)) { + return json; + } + return { + + 'photos': json['photos'], + 'usage': json['usage'], + 'usageByUser': ((json['usageByUser'] as Array).map(UsageByUserDtoFromJSON)), + 'videos': json['videos'], + }; +} + +export function ServerStatsResponseDtoToJSON(value?: ServerStatsResponseDto | null): any { + if (value === undefined) { + return undefined; + } + if (value === null) { + return null; + } + return { + + 'photos': value.photos, + 'usage': value.usage, + 'usageByUser': ((value.usageByUser as Array).map(UsageByUserDtoToJSON)), + 'videos': value.videos, + }; +} + diff --git a/open-api/typescript-sdk/fetch-client/models/ServerThemeDto.ts b/open-api/typescript-sdk/fetch-client/models/ServerThemeDto.ts new file mode 100644 index 0000000000..8163273ba5 --- /dev/null +++ b/open-api/typescript-sdk/fetch-client/models/ServerThemeDto.ts @@ -0,0 +1,66 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * Immich + * Immich API + * + * The version of the OpenAPI document: 1.94.1 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + +import { exists, mapValues } from '../runtime'; +/** + * + * @export + * @interface ServerThemeDto + */ +export interface ServerThemeDto { + /** + * + * @type {string} + * @memberof ServerThemeDto + */ + customCss: string; +} + +/** + * Check if a given object implements the ServerThemeDto interface. + */ +export function instanceOfServerThemeDto(value: object): boolean { + let isInstance = true; + isInstance = isInstance && "customCss" in value; + + return isInstance; +} + +export function ServerThemeDtoFromJSON(json: any): ServerThemeDto { + return ServerThemeDtoFromJSONTyped(json, false); +} + +export function ServerThemeDtoFromJSONTyped(json: any, ignoreDiscriminator: boolean): ServerThemeDto { + if ((json === undefined) || (json === null)) { + return json; + } + return { + + 'customCss': json['customCss'], + }; +} + +export function ServerThemeDtoToJSON(value?: ServerThemeDto | null): any { + if (value === undefined) { + return undefined; + } + if (value === null) { + return null; + } + return { + + 'customCss': value.customCss, + }; +} + diff --git a/open-api/typescript-sdk/fetch-client/models/ServerVersionResponseDto.ts b/open-api/typescript-sdk/fetch-client/models/ServerVersionResponseDto.ts new file mode 100644 index 0000000000..8d0198df79 --- /dev/null +++ b/open-api/typescript-sdk/fetch-client/models/ServerVersionResponseDto.ts @@ -0,0 +1,84 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * Immich + * Immich API + * + * The version of the OpenAPI document: 1.94.1 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + +import { exists, mapValues } from '../runtime'; +/** + * + * @export + * @interface ServerVersionResponseDto + */ +export interface ServerVersionResponseDto { + /** + * + * @type {number} + * @memberof ServerVersionResponseDto + */ + major: number; + /** + * + * @type {number} + * @memberof ServerVersionResponseDto + */ + minor: number; + /** + * + * @type {number} + * @memberof ServerVersionResponseDto + */ + patch: number; +} + +/** + * Check if a given object implements the ServerVersionResponseDto interface. + */ +export function instanceOfServerVersionResponseDto(value: object): boolean { + let isInstance = true; + isInstance = isInstance && "major" in value; + isInstance = isInstance && "minor" in value; + isInstance = isInstance && "patch" in value; + + return isInstance; +} + +export function ServerVersionResponseDtoFromJSON(json: any): ServerVersionResponseDto { + return ServerVersionResponseDtoFromJSONTyped(json, false); +} + +export function ServerVersionResponseDtoFromJSONTyped(json: any, ignoreDiscriminator: boolean): ServerVersionResponseDto { + if ((json === undefined) || (json === null)) { + return json; + } + return { + + 'major': json['major'], + 'minor': json['minor'], + 'patch': json['patch'], + }; +} + +export function ServerVersionResponseDtoToJSON(value?: ServerVersionResponseDto | null): any { + if (value === undefined) { + return undefined; + } + if (value === null) { + return null; + } + return { + + 'major': value.major, + 'minor': value.minor, + 'patch': value.patch, + }; +} + diff --git a/open-api/typescript-sdk/fetch-client/models/SharedLinkCreateDto.ts b/open-api/typescript-sdk/fetch-client/models/SharedLinkCreateDto.ts new file mode 100644 index 0000000000..af4d43f456 --- /dev/null +++ b/open-api/typescript-sdk/fetch-client/models/SharedLinkCreateDto.ts @@ -0,0 +1,137 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * Immich + * Immich API + * + * The version of the OpenAPI document: 1.94.1 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + +import { exists, mapValues } from '../runtime'; +import type { SharedLinkType } from './SharedLinkType'; +import { + SharedLinkTypeFromJSON, + SharedLinkTypeFromJSONTyped, + SharedLinkTypeToJSON, +} from './SharedLinkType'; + +/** + * + * @export + * @interface SharedLinkCreateDto + */ +export interface SharedLinkCreateDto { + /** + * + * @type {string} + * @memberof SharedLinkCreateDto + */ + albumId?: string; + /** + * + * @type {boolean} + * @memberof SharedLinkCreateDto + */ + allowDownload?: boolean; + /** + * + * @type {boolean} + * @memberof SharedLinkCreateDto + */ + allowUpload?: boolean; + /** + * + * @type {Array} + * @memberof SharedLinkCreateDto + */ + assetIds?: Array; + /** + * + * @type {string} + * @memberof SharedLinkCreateDto + */ + description?: string; + /** + * + * @type {Date} + * @memberof SharedLinkCreateDto + */ + expiresAt?: Date | null; + /** + * + * @type {string} + * @memberof SharedLinkCreateDto + */ + password?: string; + /** + * + * @type {boolean} + * @memberof SharedLinkCreateDto + */ + showMetadata?: boolean; + /** + * + * @type {SharedLinkType} + * @memberof SharedLinkCreateDto + */ + type: SharedLinkType; +} + +/** + * Check if a given object implements the SharedLinkCreateDto interface. + */ +export function instanceOfSharedLinkCreateDto(value: object): boolean { + let isInstance = true; + isInstance = isInstance && "type" in value; + + return isInstance; +} + +export function SharedLinkCreateDtoFromJSON(json: any): SharedLinkCreateDto { + return SharedLinkCreateDtoFromJSONTyped(json, false); +} + +export function SharedLinkCreateDtoFromJSONTyped(json: any, ignoreDiscriminator: boolean): SharedLinkCreateDto { + if ((json === undefined) || (json === null)) { + return json; + } + return { + + 'albumId': !exists(json, 'albumId') ? undefined : json['albumId'], + 'allowDownload': !exists(json, 'allowDownload') ? undefined : json['allowDownload'], + 'allowUpload': !exists(json, 'allowUpload') ? undefined : json['allowUpload'], + 'assetIds': !exists(json, 'assetIds') ? undefined : json['assetIds'], + 'description': !exists(json, 'description') ? undefined : json['description'], + 'expiresAt': !exists(json, 'expiresAt') ? undefined : (json['expiresAt'] === null ? null : new Date(json['expiresAt'])), + 'password': !exists(json, 'password') ? undefined : json['password'], + 'showMetadata': !exists(json, 'showMetadata') ? undefined : json['showMetadata'], + 'type': SharedLinkTypeFromJSON(json['type']), + }; +} + +export function SharedLinkCreateDtoToJSON(value?: SharedLinkCreateDto | null): any { + if (value === undefined) { + return undefined; + } + if (value === null) { + return null; + } + return { + + 'albumId': value.albumId, + 'allowDownload': value.allowDownload, + 'allowUpload': value.allowUpload, + 'assetIds': value.assetIds, + 'description': value.description, + 'expiresAt': value.expiresAt === undefined ? undefined : (value.expiresAt === null ? null : value.expiresAt.toISOString()), + 'password': value.password, + 'showMetadata': value.showMetadata, + 'type': SharedLinkTypeToJSON(value.type), + }; +} + diff --git a/open-api/typescript-sdk/fetch-client/models/SharedLinkEditDto.ts b/open-api/typescript-sdk/fetch-client/models/SharedLinkEditDto.ts new file mode 100644 index 0000000000..12eb5da76f --- /dev/null +++ b/open-api/typescript-sdk/fetch-client/models/SharedLinkEditDto.ts @@ -0,0 +1,115 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * Immich + * Immich API + * + * The version of the OpenAPI document: 1.94.1 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + +import { exists, mapValues } from '../runtime'; +/** + * + * @export + * @interface SharedLinkEditDto + */ +export interface SharedLinkEditDto { + /** + * + * @type {boolean} + * @memberof SharedLinkEditDto + */ + allowDownload?: boolean; + /** + * + * @type {boolean} + * @memberof SharedLinkEditDto + */ + allowUpload?: boolean; + /** + * Few clients cannot send null to set the expiryTime to never. + * Setting this flag and not sending expiryAt is considered as null instead. + * Clients that can send null values can ignore this. + * @type {boolean} + * @memberof SharedLinkEditDto + */ + changeExpiryTime?: boolean; + /** + * + * @type {string} + * @memberof SharedLinkEditDto + */ + description?: string; + /** + * + * @type {Date} + * @memberof SharedLinkEditDto + */ + expiresAt?: Date | null; + /** + * + * @type {string} + * @memberof SharedLinkEditDto + */ + password?: string; + /** + * + * @type {boolean} + * @memberof SharedLinkEditDto + */ + showMetadata?: boolean; +} + +/** + * Check if a given object implements the SharedLinkEditDto interface. + */ +export function instanceOfSharedLinkEditDto(value: object): boolean { + let isInstance = true; + + return isInstance; +} + +export function SharedLinkEditDtoFromJSON(json: any): SharedLinkEditDto { + return SharedLinkEditDtoFromJSONTyped(json, false); +} + +export function SharedLinkEditDtoFromJSONTyped(json: any, ignoreDiscriminator: boolean): SharedLinkEditDto { + if ((json === undefined) || (json === null)) { + return json; + } + return { + + 'allowDownload': !exists(json, 'allowDownload') ? undefined : json['allowDownload'], + 'allowUpload': !exists(json, 'allowUpload') ? undefined : json['allowUpload'], + 'changeExpiryTime': !exists(json, 'changeExpiryTime') ? undefined : json['changeExpiryTime'], + 'description': !exists(json, 'description') ? undefined : json['description'], + 'expiresAt': !exists(json, 'expiresAt') ? undefined : (json['expiresAt'] === null ? null : new Date(json['expiresAt'])), + 'password': !exists(json, 'password') ? undefined : json['password'], + 'showMetadata': !exists(json, 'showMetadata') ? undefined : json['showMetadata'], + }; +} + +export function SharedLinkEditDtoToJSON(value?: SharedLinkEditDto | null): any { + if (value === undefined) { + return undefined; + } + if (value === null) { + return null; + } + return { + + 'allowDownload': value.allowDownload, + 'allowUpload': value.allowUpload, + 'changeExpiryTime': value.changeExpiryTime, + 'description': value.description, + 'expiresAt': value.expiresAt === undefined ? undefined : (value.expiresAt === null ? null : value.expiresAt.toISOString()), + 'password': value.password, + 'showMetadata': value.showMetadata, + }; +} + diff --git a/open-api/typescript-sdk/fetch-client/models/SharedLinkResponseDto.ts b/open-api/typescript-sdk/fetch-client/models/SharedLinkResponseDto.ts new file mode 100644 index 0000000000..6f56c90176 --- /dev/null +++ b/open-api/typescript-sdk/fetch-client/models/SharedLinkResponseDto.ts @@ -0,0 +1,200 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * Immich + * Immich API + * + * The version of the OpenAPI document: 1.94.1 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + +import { exists, mapValues } from '../runtime'; +import type { AlbumResponseDto } from './AlbumResponseDto'; +import { + AlbumResponseDtoFromJSON, + AlbumResponseDtoFromJSONTyped, + AlbumResponseDtoToJSON, +} from './AlbumResponseDto'; +import type { AssetResponseDto } from './AssetResponseDto'; +import { + AssetResponseDtoFromJSON, + AssetResponseDtoFromJSONTyped, + AssetResponseDtoToJSON, +} from './AssetResponseDto'; +import type { SharedLinkType } from './SharedLinkType'; +import { + SharedLinkTypeFromJSON, + SharedLinkTypeFromJSONTyped, + SharedLinkTypeToJSON, +} from './SharedLinkType'; + +/** + * + * @export + * @interface SharedLinkResponseDto + */ +export interface SharedLinkResponseDto { + /** + * + * @type {AlbumResponseDto} + * @memberof SharedLinkResponseDto + */ + album?: AlbumResponseDto; + /** + * + * @type {boolean} + * @memberof SharedLinkResponseDto + */ + allowDownload: boolean; + /** + * + * @type {boolean} + * @memberof SharedLinkResponseDto + */ + allowUpload: boolean; + /** + * + * @type {Array} + * @memberof SharedLinkResponseDto + */ + assets: Array; + /** + * + * @type {Date} + * @memberof SharedLinkResponseDto + */ + createdAt: Date; + /** + * + * @type {string} + * @memberof SharedLinkResponseDto + */ + description: string | null; + /** + * + * @type {Date} + * @memberof SharedLinkResponseDto + */ + expiresAt: Date | null; + /** + * + * @type {string} + * @memberof SharedLinkResponseDto + */ + id: string; + /** + * + * @type {string} + * @memberof SharedLinkResponseDto + */ + key: string; + /** + * + * @type {string} + * @memberof SharedLinkResponseDto + */ + password: string | null; + /** + * + * @type {boolean} + * @memberof SharedLinkResponseDto + */ + showMetadata: boolean; + /** + * + * @type {string} + * @memberof SharedLinkResponseDto + */ + token?: string | null; + /** + * + * @type {SharedLinkType} + * @memberof SharedLinkResponseDto + */ + type: SharedLinkType; + /** + * + * @type {string} + * @memberof SharedLinkResponseDto + */ + userId: string; +} + +/** + * Check if a given object implements the SharedLinkResponseDto interface. + */ +export function instanceOfSharedLinkResponseDto(value: object): boolean { + let isInstance = true; + isInstance = isInstance && "allowDownload" in value; + isInstance = isInstance && "allowUpload" in value; + isInstance = isInstance && "assets" in value; + isInstance = isInstance && "createdAt" in value; + isInstance = isInstance && "description" in value; + isInstance = isInstance && "expiresAt" in value; + isInstance = isInstance && "id" in value; + isInstance = isInstance && "key" in value; + isInstance = isInstance && "password" in value; + isInstance = isInstance && "showMetadata" in value; + isInstance = isInstance && "type" in value; + isInstance = isInstance && "userId" in value; + + return isInstance; +} + +export function SharedLinkResponseDtoFromJSON(json: any): SharedLinkResponseDto { + return SharedLinkResponseDtoFromJSONTyped(json, false); +} + +export function SharedLinkResponseDtoFromJSONTyped(json: any, ignoreDiscriminator: boolean): SharedLinkResponseDto { + if ((json === undefined) || (json === null)) { + return json; + } + return { + + 'album': !exists(json, 'album') ? undefined : AlbumResponseDtoFromJSON(json['album']), + 'allowDownload': json['allowDownload'], + 'allowUpload': json['allowUpload'], + 'assets': ((json['assets'] as Array).map(AssetResponseDtoFromJSON)), + 'createdAt': (new Date(json['createdAt'])), + 'description': json['description'], + 'expiresAt': (json['expiresAt'] === null ? null : new Date(json['expiresAt'])), + 'id': json['id'], + 'key': json['key'], + 'password': json['password'], + 'showMetadata': json['showMetadata'], + 'token': !exists(json, 'token') ? undefined : json['token'], + 'type': SharedLinkTypeFromJSON(json['type']), + 'userId': json['userId'], + }; +} + +export function SharedLinkResponseDtoToJSON(value?: SharedLinkResponseDto | null): any { + if (value === undefined) { + return undefined; + } + if (value === null) { + return null; + } + return { + + 'album': AlbumResponseDtoToJSON(value.album), + 'allowDownload': value.allowDownload, + 'allowUpload': value.allowUpload, + 'assets': ((value.assets as Array).map(AssetResponseDtoToJSON)), + 'createdAt': (value.createdAt.toISOString()), + 'description': value.description, + 'expiresAt': (value.expiresAt === null ? null : value.expiresAt.toISOString()), + 'id': value.id, + 'key': value.key, + 'password': value.password, + 'showMetadata': value.showMetadata, + 'token': value.token, + 'type': SharedLinkTypeToJSON(value.type), + 'userId': value.userId, + }; +} + diff --git a/open-api/typescript-sdk/fetch-client/models/SharedLinkType.ts b/open-api/typescript-sdk/fetch-client/models/SharedLinkType.ts new file mode 100644 index 0000000000..901c73c9c0 --- /dev/null +++ b/open-api/typescript-sdk/fetch-client/models/SharedLinkType.ts @@ -0,0 +1,38 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * Immich + * Immich API + * + * The version of the OpenAPI document: 1.94.1 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + + +/** + * + * @export + */ +export const SharedLinkType = { + Album: 'ALBUM', + Individual: 'INDIVIDUAL' +} as const; +export type SharedLinkType = typeof SharedLinkType[keyof typeof SharedLinkType]; + + +export function SharedLinkTypeFromJSON(json: any): SharedLinkType { + return SharedLinkTypeFromJSONTyped(json, false); +} + +export function SharedLinkTypeFromJSONTyped(json: any, ignoreDiscriminator: boolean): SharedLinkType { + return json as SharedLinkType; +} + +export function SharedLinkTypeToJSON(value?: SharedLinkType | null): any { + return value as any; +} + diff --git a/open-api/typescript-sdk/fetch-client/models/SignUpDto.ts b/open-api/typescript-sdk/fetch-client/models/SignUpDto.ts new file mode 100644 index 0000000000..681fbf7519 --- /dev/null +++ b/open-api/typescript-sdk/fetch-client/models/SignUpDto.ts @@ -0,0 +1,84 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * Immich + * Immich API + * + * The version of the OpenAPI document: 1.94.1 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + +import { exists, mapValues } from '../runtime'; +/** + * + * @export + * @interface SignUpDto + */ +export interface SignUpDto { + /** + * + * @type {string} + * @memberof SignUpDto + */ + email: string; + /** + * + * @type {string} + * @memberof SignUpDto + */ + name: string; + /** + * + * @type {string} + * @memberof SignUpDto + */ + password: string; +} + +/** + * Check if a given object implements the SignUpDto interface. + */ +export function instanceOfSignUpDto(value: object): boolean { + let isInstance = true; + isInstance = isInstance && "email" in value; + isInstance = isInstance && "name" in value; + isInstance = isInstance && "password" in value; + + return isInstance; +} + +export function SignUpDtoFromJSON(json: any): SignUpDto { + return SignUpDtoFromJSONTyped(json, false); +} + +export function SignUpDtoFromJSONTyped(json: any, ignoreDiscriminator: boolean): SignUpDto { + if ((json === undefined) || (json === null)) { + return json; + } + return { + + 'email': json['email'], + 'name': json['name'], + 'password': json['password'], + }; +} + +export function SignUpDtoToJSON(value?: SignUpDto | null): any { + if (value === undefined) { + return undefined; + } + if (value === null) { + return null; + } + return { + + 'email': value.email, + 'name': value.name, + 'password': value.password, + }; +} + diff --git a/open-api/typescript-sdk/fetch-client/models/SmartInfoResponseDto.ts b/open-api/typescript-sdk/fetch-client/models/SmartInfoResponseDto.ts new file mode 100644 index 0000000000..0b652fe7c2 --- /dev/null +++ b/open-api/typescript-sdk/fetch-client/models/SmartInfoResponseDto.ts @@ -0,0 +1,73 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * Immich + * Immich API + * + * The version of the OpenAPI document: 1.94.1 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + +import { exists, mapValues } from '../runtime'; +/** + * + * @export + * @interface SmartInfoResponseDto + */ +export interface SmartInfoResponseDto { + /** + * + * @type {Array} + * @memberof SmartInfoResponseDto + */ + objects?: Array | null; + /** + * + * @type {Array} + * @memberof SmartInfoResponseDto + */ + tags?: Array | null; +} + +/** + * Check if a given object implements the SmartInfoResponseDto interface. + */ +export function instanceOfSmartInfoResponseDto(value: object): boolean { + let isInstance = true; + + return isInstance; +} + +export function SmartInfoResponseDtoFromJSON(json: any): SmartInfoResponseDto { + return SmartInfoResponseDtoFromJSONTyped(json, false); +} + +export function SmartInfoResponseDtoFromJSONTyped(json: any, ignoreDiscriminator: boolean): SmartInfoResponseDto { + if ((json === undefined) || (json === null)) { + return json; + } + return { + + 'objects': !exists(json, 'objects') ? undefined : json['objects'], + 'tags': !exists(json, 'tags') ? undefined : json['tags'], + }; +} + +export function SmartInfoResponseDtoToJSON(value?: SmartInfoResponseDto | null): any { + if (value === undefined) { + return undefined; + } + if (value === null) { + return null; + } + return { + + 'objects': value.objects, + 'tags': value.tags, + }; +} + diff --git a/open-api/typescript-sdk/fetch-client/models/SystemConfigDto.ts b/open-api/typescript-sdk/fetch-client/models/SystemConfigDto.ts new file mode 100644 index 0000000000..99504d6f51 --- /dev/null +++ b/open-api/typescript-sdk/fetch-client/models/SystemConfigDto.ts @@ -0,0 +1,283 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * Immich + * Immich API + * + * The version of the OpenAPI document: 1.94.1 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + +import { exists, mapValues } from '../runtime'; +import type { SystemConfigFFmpegDto } from './SystemConfigFFmpegDto'; +import { + SystemConfigFFmpegDtoFromJSON, + SystemConfigFFmpegDtoFromJSONTyped, + SystemConfigFFmpegDtoToJSON, +} from './SystemConfigFFmpegDto'; +import type { SystemConfigJobDto } from './SystemConfigJobDto'; +import { + SystemConfigJobDtoFromJSON, + SystemConfigJobDtoFromJSONTyped, + SystemConfigJobDtoToJSON, +} from './SystemConfigJobDto'; +import type { SystemConfigLibraryDto } from './SystemConfigLibraryDto'; +import { + SystemConfigLibraryDtoFromJSON, + SystemConfigLibraryDtoFromJSONTyped, + SystemConfigLibraryDtoToJSON, +} from './SystemConfigLibraryDto'; +import type { SystemConfigLoggingDto } from './SystemConfigLoggingDto'; +import { + SystemConfigLoggingDtoFromJSON, + SystemConfigLoggingDtoFromJSONTyped, + SystemConfigLoggingDtoToJSON, +} from './SystemConfigLoggingDto'; +import type { SystemConfigMachineLearningDto } from './SystemConfigMachineLearningDto'; +import { + SystemConfigMachineLearningDtoFromJSON, + SystemConfigMachineLearningDtoFromJSONTyped, + SystemConfigMachineLearningDtoToJSON, +} from './SystemConfigMachineLearningDto'; +import type { SystemConfigMapDto } from './SystemConfigMapDto'; +import { + SystemConfigMapDtoFromJSON, + SystemConfigMapDtoFromJSONTyped, + SystemConfigMapDtoToJSON, +} from './SystemConfigMapDto'; +import type { SystemConfigNewVersionCheckDto } from './SystemConfigNewVersionCheckDto'; +import { + SystemConfigNewVersionCheckDtoFromJSON, + SystemConfigNewVersionCheckDtoFromJSONTyped, + SystemConfigNewVersionCheckDtoToJSON, +} from './SystemConfigNewVersionCheckDto'; +import type { SystemConfigOAuthDto } from './SystemConfigOAuthDto'; +import { + SystemConfigOAuthDtoFromJSON, + SystemConfigOAuthDtoFromJSONTyped, + SystemConfigOAuthDtoToJSON, +} from './SystemConfigOAuthDto'; +import type { SystemConfigPasswordLoginDto } from './SystemConfigPasswordLoginDto'; +import { + SystemConfigPasswordLoginDtoFromJSON, + SystemConfigPasswordLoginDtoFromJSONTyped, + SystemConfigPasswordLoginDtoToJSON, +} from './SystemConfigPasswordLoginDto'; +import type { SystemConfigReverseGeocodingDto } from './SystemConfigReverseGeocodingDto'; +import { + SystemConfigReverseGeocodingDtoFromJSON, + SystemConfigReverseGeocodingDtoFromJSONTyped, + SystemConfigReverseGeocodingDtoToJSON, +} from './SystemConfigReverseGeocodingDto'; +import type { SystemConfigServerDto } from './SystemConfigServerDto'; +import { + SystemConfigServerDtoFromJSON, + SystemConfigServerDtoFromJSONTyped, + SystemConfigServerDtoToJSON, +} from './SystemConfigServerDto'; +import type { SystemConfigStorageTemplateDto } from './SystemConfigStorageTemplateDto'; +import { + SystemConfigStorageTemplateDtoFromJSON, + SystemConfigStorageTemplateDtoFromJSONTyped, + SystemConfigStorageTemplateDtoToJSON, +} from './SystemConfigStorageTemplateDto'; +import type { SystemConfigThemeDto } from './SystemConfigThemeDto'; +import { + SystemConfigThemeDtoFromJSON, + SystemConfigThemeDtoFromJSONTyped, + SystemConfigThemeDtoToJSON, +} from './SystemConfigThemeDto'; +import type { SystemConfigThumbnailDto } from './SystemConfigThumbnailDto'; +import { + SystemConfigThumbnailDtoFromJSON, + SystemConfigThumbnailDtoFromJSONTyped, + SystemConfigThumbnailDtoToJSON, +} from './SystemConfigThumbnailDto'; +import type { SystemConfigTrashDto } from './SystemConfigTrashDto'; +import { + SystemConfigTrashDtoFromJSON, + SystemConfigTrashDtoFromJSONTyped, + SystemConfigTrashDtoToJSON, +} from './SystemConfigTrashDto'; + +/** + * + * @export + * @interface SystemConfigDto + */ +export interface SystemConfigDto { + /** + * + * @type {SystemConfigFFmpegDto} + * @memberof SystemConfigDto + */ + ffmpeg: SystemConfigFFmpegDto; + /** + * + * @type {SystemConfigJobDto} + * @memberof SystemConfigDto + */ + job: SystemConfigJobDto; + /** + * + * @type {SystemConfigLibraryDto} + * @memberof SystemConfigDto + */ + library: SystemConfigLibraryDto; + /** + * + * @type {SystemConfigLoggingDto} + * @memberof SystemConfigDto + */ + logging: SystemConfigLoggingDto; + /** + * + * @type {SystemConfigMachineLearningDto} + * @memberof SystemConfigDto + */ + machineLearning: SystemConfigMachineLearningDto; + /** + * + * @type {SystemConfigMapDto} + * @memberof SystemConfigDto + */ + map: SystemConfigMapDto; + /** + * + * @type {SystemConfigNewVersionCheckDto} + * @memberof SystemConfigDto + */ + newVersionCheck: SystemConfigNewVersionCheckDto; + /** + * + * @type {SystemConfigOAuthDto} + * @memberof SystemConfigDto + */ + oauth: SystemConfigOAuthDto; + /** + * + * @type {SystemConfigPasswordLoginDto} + * @memberof SystemConfigDto + */ + passwordLogin: SystemConfigPasswordLoginDto; + /** + * + * @type {SystemConfigReverseGeocodingDto} + * @memberof SystemConfigDto + */ + reverseGeocoding: SystemConfigReverseGeocodingDto; + /** + * + * @type {SystemConfigServerDto} + * @memberof SystemConfigDto + */ + server: SystemConfigServerDto; + /** + * + * @type {SystemConfigStorageTemplateDto} + * @memberof SystemConfigDto + */ + storageTemplate: SystemConfigStorageTemplateDto; + /** + * + * @type {SystemConfigThemeDto} + * @memberof SystemConfigDto + */ + theme: SystemConfigThemeDto; + /** + * + * @type {SystemConfigThumbnailDto} + * @memberof SystemConfigDto + */ + thumbnail: SystemConfigThumbnailDto; + /** + * + * @type {SystemConfigTrashDto} + * @memberof SystemConfigDto + */ + trash: SystemConfigTrashDto; +} + +/** + * Check if a given object implements the SystemConfigDto interface. + */ +export function instanceOfSystemConfigDto(value: object): boolean { + let isInstance = true; + isInstance = isInstance && "ffmpeg" in value; + isInstance = isInstance && "job" in value; + isInstance = isInstance && "library" in value; + isInstance = isInstance && "logging" in value; + isInstance = isInstance && "machineLearning" in value; + isInstance = isInstance && "map" in value; + isInstance = isInstance && "newVersionCheck" in value; + isInstance = isInstance && "oauth" in value; + isInstance = isInstance && "passwordLogin" in value; + isInstance = isInstance && "reverseGeocoding" in value; + isInstance = isInstance && "server" in value; + isInstance = isInstance && "storageTemplate" in value; + isInstance = isInstance && "theme" in value; + isInstance = isInstance && "thumbnail" in value; + isInstance = isInstance && "trash" in value; + + return isInstance; +} + +export function SystemConfigDtoFromJSON(json: any): SystemConfigDto { + return SystemConfigDtoFromJSONTyped(json, false); +} + +export function SystemConfigDtoFromJSONTyped(json: any, ignoreDiscriminator: boolean): SystemConfigDto { + if ((json === undefined) || (json === null)) { + return json; + } + return { + + 'ffmpeg': SystemConfigFFmpegDtoFromJSON(json['ffmpeg']), + 'job': SystemConfigJobDtoFromJSON(json['job']), + 'library': SystemConfigLibraryDtoFromJSON(json['library']), + 'logging': SystemConfigLoggingDtoFromJSON(json['logging']), + 'machineLearning': SystemConfigMachineLearningDtoFromJSON(json['machineLearning']), + 'map': SystemConfigMapDtoFromJSON(json['map']), + 'newVersionCheck': SystemConfigNewVersionCheckDtoFromJSON(json['newVersionCheck']), + 'oauth': SystemConfigOAuthDtoFromJSON(json['oauth']), + 'passwordLogin': SystemConfigPasswordLoginDtoFromJSON(json['passwordLogin']), + 'reverseGeocoding': SystemConfigReverseGeocodingDtoFromJSON(json['reverseGeocoding']), + 'server': SystemConfigServerDtoFromJSON(json['server']), + 'storageTemplate': SystemConfigStorageTemplateDtoFromJSON(json['storageTemplate']), + 'theme': SystemConfigThemeDtoFromJSON(json['theme']), + 'thumbnail': SystemConfigThumbnailDtoFromJSON(json['thumbnail']), + 'trash': SystemConfigTrashDtoFromJSON(json['trash']), + }; +} + +export function SystemConfigDtoToJSON(value?: SystemConfigDto | null): any { + if (value === undefined) { + return undefined; + } + if (value === null) { + return null; + } + return { + + 'ffmpeg': SystemConfigFFmpegDtoToJSON(value.ffmpeg), + 'job': SystemConfigJobDtoToJSON(value.job), + 'library': SystemConfigLibraryDtoToJSON(value.library), + 'logging': SystemConfigLoggingDtoToJSON(value.logging), + 'machineLearning': SystemConfigMachineLearningDtoToJSON(value.machineLearning), + 'map': SystemConfigMapDtoToJSON(value.map), + 'newVersionCheck': SystemConfigNewVersionCheckDtoToJSON(value.newVersionCheck), + 'oauth': SystemConfigOAuthDtoToJSON(value.oauth), + 'passwordLogin': SystemConfigPasswordLoginDtoToJSON(value.passwordLogin), + 'reverseGeocoding': SystemConfigReverseGeocodingDtoToJSON(value.reverseGeocoding), + 'server': SystemConfigServerDtoToJSON(value.server), + 'storageTemplate': SystemConfigStorageTemplateDtoToJSON(value.storageTemplate), + 'theme': SystemConfigThemeDtoToJSON(value.theme), + 'thumbnail': SystemConfigThumbnailDtoToJSON(value.thumbnail), + 'trash': SystemConfigTrashDtoToJSON(value.trash), + }; +} + diff --git a/open-api/typescript-sdk/fetch-client/models/SystemConfigFFmpegDto.ts b/open-api/typescript-sdk/fetch-client/models/SystemConfigFFmpegDto.ts new file mode 100644 index 0000000000..aec8ff48d7 --- /dev/null +++ b/open-api/typescript-sdk/fetch-client/models/SystemConfigFFmpegDto.ts @@ -0,0 +1,274 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * Immich + * Immich API + * + * The version of the OpenAPI document: 1.94.1 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + +import { exists, mapValues } from '../runtime'; +import type { AudioCodec } from './AudioCodec'; +import { + AudioCodecFromJSON, + AudioCodecFromJSONTyped, + AudioCodecToJSON, +} from './AudioCodec'; +import type { CQMode } from './CQMode'; +import { + CQModeFromJSON, + CQModeFromJSONTyped, + CQModeToJSON, +} from './CQMode'; +import type { ToneMapping } from './ToneMapping'; +import { + ToneMappingFromJSON, + ToneMappingFromJSONTyped, + ToneMappingToJSON, +} from './ToneMapping'; +import type { TranscodeHWAccel } from './TranscodeHWAccel'; +import { + TranscodeHWAccelFromJSON, + TranscodeHWAccelFromJSONTyped, + TranscodeHWAccelToJSON, +} from './TranscodeHWAccel'; +import type { TranscodePolicy } from './TranscodePolicy'; +import { + TranscodePolicyFromJSON, + TranscodePolicyFromJSONTyped, + TranscodePolicyToJSON, +} from './TranscodePolicy'; +import type { VideoCodec } from './VideoCodec'; +import { + VideoCodecFromJSON, + VideoCodecFromJSONTyped, + VideoCodecToJSON, +} from './VideoCodec'; + +/** + * + * @export + * @interface SystemConfigFFmpegDto + */ +export interface SystemConfigFFmpegDto { + /** + * + * @type {TranscodeHWAccel} + * @memberof SystemConfigFFmpegDto + */ + accel: TranscodeHWAccel; + /** + * + * @type {Array} + * @memberof SystemConfigFFmpegDto + */ + acceptedAudioCodecs: Array; + /** + * + * @type {Array} + * @memberof SystemConfigFFmpegDto + */ + acceptedVideoCodecs: Array; + /** + * + * @type {number} + * @memberof SystemConfigFFmpegDto + */ + bframes: number; + /** + * + * @type {CQMode} + * @memberof SystemConfigFFmpegDto + */ + cqMode: CQMode; + /** + * + * @type {number} + * @memberof SystemConfigFFmpegDto + */ + crf: number; + /** + * + * @type {number} + * @memberof SystemConfigFFmpegDto + */ + gopSize: number; + /** + * + * @type {string} + * @memberof SystemConfigFFmpegDto + */ + maxBitrate: string; + /** + * + * @type {number} + * @memberof SystemConfigFFmpegDto + */ + npl: number; + /** + * + * @type {string} + * @memberof SystemConfigFFmpegDto + */ + preferredHwDevice: string; + /** + * + * @type {string} + * @memberof SystemConfigFFmpegDto + */ + preset: string; + /** + * + * @type {number} + * @memberof SystemConfigFFmpegDto + */ + refs: number; + /** + * + * @type {AudioCodec} + * @memberof SystemConfigFFmpegDto + */ + targetAudioCodec: AudioCodec; + /** + * + * @type {string} + * @memberof SystemConfigFFmpegDto + */ + targetResolution: string; + /** + * + * @type {VideoCodec} + * @memberof SystemConfigFFmpegDto + */ + targetVideoCodec: VideoCodec; + /** + * + * @type {boolean} + * @memberof SystemConfigFFmpegDto + */ + temporalAQ: boolean; + /** + * + * @type {number} + * @memberof SystemConfigFFmpegDto + */ + threads: number; + /** + * + * @type {ToneMapping} + * @memberof SystemConfigFFmpegDto + */ + tonemap: ToneMapping; + /** + * + * @type {TranscodePolicy} + * @memberof SystemConfigFFmpegDto + */ + transcode: TranscodePolicy; + /** + * + * @type {boolean} + * @memberof SystemConfigFFmpegDto + */ + twoPass: boolean; +} + +/** + * Check if a given object implements the SystemConfigFFmpegDto interface. + */ +export function instanceOfSystemConfigFFmpegDto(value: object): boolean { + let isInstance = true; + isInstance = isInstance && "accel" in value; + isInstance = isInstance && "acceptedAudioCodecs" in value; + isInstance = isInstance && "acceptedVideoCodecs" in value; + isInstance = isInstance && "bframes" in value; + isInstance = isInstance && "cqMode" in value; + isInstance = isInstance && "crf" in value; + isInstance = isInstance && "gopSize" in value; + isInstance = isInstance && "maxBitrate" in value; + isInstance = isInstance && "npl" in value; + isInstance = isInstance && "preferredHwDevice" in value; + isInstance = isInstance && "preset" in value; + isInstance = isInstance && "refs" in value; + isInstance = isInstance && "targetAudioCodec" in value; + isInstance = isInstance && "targetResolution" in value; + isInstance = isInstance && "targetVideoCodec" in value; + isInstance = isInstance && "temporalAQ" in value; + isInstance = isInstance && "threads" in value; + isInstance = isInstance && "tonemap" in value; + isInstance = isInstance && "transcode" in value; + isInstance = isInstance && "twoPass" in value; + + return isInstance; +} + +export function SystemConfigFFmpegDtoFromJSON(json: any): SystemConfigFFmpegDto { + return SystemConfigFFmpegDtoFromJSONTyped(json, false); +} + +export function SystemConfigFFmpegDtoFromJSONTyped(json: any, ignoreDiscriminator: boolean): SystemConfigFFmpegDto { + if ((json === undefined) || (json === null)) { + return json; + } + return { + + 'accel': TranscodeHWAccelFromJSON(json['accel']), + 'acceptedAudioCodecs': ((json['acceptedAudioCodecs'] as Array).map(AudioCodecFromJSON)), + 'acceptedVideoCodecs': ((json['acceptedVideoCodecs'] as Array).map(VideoCodecFromJSON)), + 'bframes': json['bframes'], + 'cqMode': CQModeFromJSON(json['cqMode']), + 'crf': json['crf'], + 'gopSize': json['gopSize'], + 'maxBitrate': json['maxBitrate'], + 'npl': json['npl'], + 'preferredHwDevice': json['preferredHwDevice'], + 'preset': json['preset'], + 'refs': json['refs'], + 'targetAudioCodec': AudioCodecFromJSON(json['targetAudioCodec']), + 'targetResolution': json['targetResolution'], + 'targetVideoCodec': VideoCodecFromJSON(json['targetVideoCodec']), + 'temporalAQ': json['temporalAQ'], + 'threads': json['threads'], + 'tonemap': ToneMappingFromJSON(json['tonemap']), + 'transcode': TranscodePolicyFromJSON(json['transcode']), + 'twoPass': json['twoPass'], + }; +} + +export function SystemConfigFFmpegDtoToJSON(value?: SystemConfigFFmpegDto | null): any { + if (value === undefined) { + return undefined; + } + if (value === null) { + return null; + } + return { + + 'accel': TranscodeHWAccelToJSON(value.accel), + 'acceptedAudioCodecs': ((value.acceptedAudioCodecs as Array).map(AudioCodecToJSON)), + 'acceptedVideoCodecs': ((value.acceptedVideoCodecs as Array).map(VideoCodecToJSON)), + 'bframes': value.bframes, + 'cqMode': CQModeToJSON(value.cqMode), + 'crf': value.crf, + 'gopSize': value.gopSize, + 'maxBitrate': value.maxBitrate, + 'npl': value.npl, + 'preferredHwDevice': value.preferredHwDevice, + 'preset': value.preset, + 'refs': value.refs, + 'targetAudioCodec': AudioCodecToJSON(value.targetAudioCodec), + 'targetResolution': value.targetResolution, + 'targetVideoCodec': VideoCodecToJSON(value.targetVideoCodec), + 'temporalAQ': value.temporalAQ, + 'threads': value.threads, + 'tonemap': ToneMappingToJSON(value.tonemap), + 'transcode': TranscodePolicyToJSON(value.transcode), + 'twoPass': value.twoPass, + }; +} + diff --git a/open-api/typescript-sdk/fetch-client/models/SystemConfigJobDto.ts b/open-api/typescript-sdk/fetch-client/models/SystemConfigJobDto.ts new file mode 100644 index 0000000000..df18ca0c19 --- /dev/null +++ b/open-api/typescript-sdk/fetch-client/models/SystemConfigJobDto.ts @@ -0,0 +1,154 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * Immich + * Immich API + * + * The version of the OpenAPI document: 1.94.1 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + +import { exists, mapValues } from '../runtime'; +import type { JobSettingsDto } from './JobSettingsDto'; +import { + JobSettingsDtoFromJSON, + JobSettingsDtoFromJSONTyped, + JobSettingsDtoToJSON, +} from './JobSettingsDto'; + +/** + * + * @export + * @interface SystemConfigJobDto + */ +export interface SystemConfigJobDto { + /** + * + * @type {JobSettingsDto} + * @memberof SystemConfigJobDto + */ + backgroundTask: JobSettingsDto; + /** + * + * @type {JobSettingsDto} + * @memberof SystemConfigJobDto + */ + faceDetection: JobSettingsDto; + /** + * + * @type {JobSettingsDto} + * @memberof SystemConfigJobDto + */ + library: JobSettingsDto; + /** + * + * @type {JobSettingsDto} + * @memberof SystemConfigJobDto + */ + metadataExtraction: JobSettingsDto; + /** + * + * @type {JobSettingsDto} + * @memberof SystemConfigJobDto + */ + migration: JobSettingsDto; + /** + * + * @type {JobSettingsDto} + * @memberof SystemConfigJobDto + */ + search: JobSettingsDto; + /** + * + * @type {JobSettingsDto} + * @memberof SystemConfigJobDto + */ + sidecar: JobSettingsDto; + /** + * + * @type {JobSettingsDto} + * @memberof SystemConfigJobDto + */ + smartSearch: JobSettingsDto; + /** + * + * @type {JobSettingsDto} + * @memberof SystemConfigJobDto + */ + thumbnailGeneration: JobSettingsDto; + /** + * + * @type {JobSettingsDto} + * @memberof SystemConfigJobDto + */ + videoConversion: JobSettingsDto; +} + +/** + * Check if a given object implements the SystemConfigJobDto interface. + */ +export function instanceOfSystemConfigJobDto(value: object): boolean { + let isInstance = true; + isInstance = isInstance && "backgroundTask" in value; + isInstance = isInstance && "faceDetection" in value; + isInstance = isInstance && "library" in value; + isInstance = isInstance && "metadataExtraction" in value; + isInstance = isInstance && "migration" in value; + isInstance = isInstance && "search" in value; + isInstance = isInstance && "sidecar" in value; + isInstance = isInstance && "smartSearch" in value; + isInstance = isInstance && "thumbnailGeneration" in value; + isInstance = isInstance && "videoConversion" in value; + + return isInstance; +} + +export function SystemConfigJobDtoFromJSON(json: any): SystemConfigJobDto { + return SystemConfigJobDtoFromJSONTyped(json, false); +} + +export function SystemConfigJobDtoFromJSONTyped(json: any, ignoreDiscriminator: boolean): SystemConfigJobDto { + if ((json === undefined) || (json === null)) { + return json; + } + return { + + 'backgroundTask': JobSettingsDtoFromJSON(json['backgroundTask']), + 'faceDetection': JobSettingsDtoFromJSON(json['faceDetection']), + 'library': JobSettingsDtoFromJSON(json['library']), + 'metadataExtraction': JobSettingsDtoFromJSON(json['metadataExtraction']), + 'migration': JobSettingsDtoFromJSON(json['migration']), + 'search': JobSettingsDtoFromJSON(json['search']), + 'sidecar': JobSettingsDtoFromJSON(json['sidecar']), + 'smartSearch': JobSettingsDtoFromJSON(json['smartSearch']), + 'thumbnailGeneration': JobSettingsDtoFromJSON(json['thumbnailGeneration']), + 'videoConversion': JobSettingsDtoFromJSON(json['videoConversion']), + }; +} + +export function SystemConfigJobDtoToJSON(value?: SystemConfigJobDto | null): any { + if (value === undefined) { + return undefined; + } + if (value === null) { + return null; + } + return { + + 'backgroundTask': JobSettingsDtoToJSON(value.backgroundTask), + 'faceDetection': JobSettingsDtoToJSON(value.faceDetection), + 'library': JobSettingsDtoToJSON(value.library), + 'metadataExtraction': JobSettingsDtoToJSON(value.metadataExtraction), + 'migration': JobSettingsDtoToJSON(value.migration), + 'search': JobSettingsDtoToJSON(value.search), + 'sidecar': JobSettingsDtoToJSON(value.sidecar), + 'smartSearch': JobSettingsDtoToJSON(value.smartSearch), + 'thumbnailGeneration': JobSettingsDtoToJSON(value.thumbnailGeneration), + 'videoConversion': JobSettingsDtoToJSON(value.videoConversion), + }; +} + diff --git a/open-api/typescript-sdk/fetch-client/models/SystemConfigLibraryDto.ts b/open-api/typescript-sdk/fetch-client/models/SystemConfigLibraryDto.ts new file mode 100644 index 0000000000..78183bd3a2 --- /dev/null +++ b/open-api/typescript-sdk/fetch-client/models/SystemConfigLibraryDto.ts @@ -0,0 +1,88 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * Immich + * Immich API + * + * The version of the OpenAPI document: 1.94.1 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + +import { exists, mapValues } from '../runtime'; +import type { SystemConfigLibraryScanDto } from './SystemConfigLibraryScanDto'; +import { + SystemConfigLibraryScanDtoFromJSON, + SystemConfigLibraryScanDtoFromJSONTyped, + SystemConfigLibraryScanDtoToJSON, +} from './SystemConfigLibraryScanDto'; +import type { SystemConfigLibraryWatchDto } from './SystemConfigLibraryWatchDto'; +import { + SystemConfigLibraryWatchDtoFromJSON, + SystemConfigLibraryWatchDtoFromJSONTyped, + SystemConfigLibraryWatchDtoToJSON, +} from './SystemConfigLibraryWatchDto'; + +/** + * + * @export + * @interface SystemConfigLibraryDto + */ +export interface SystemConfigLibraryDto { + /** + * + * @type {SystemConfigLibraryScanDto} + * @memberof SystemConfigLibraryDto + */ + scan: SystemConfigLibraryScanDto; + /** + * + * @type {SystemConfigLibraryWatchDto} + * @memberof SystemConfigLibraryDto + */ + watch: SystemConfigLibraryWatchDto; +} + +/** + * Check if a given object implements the SystemConfigLibraryDto interface. + */ +export function instanceOfSystemConfigLibraryDto(value: object): boolean { + let isInstance = true; + isInstance = isInstance && "scan" in value; + isInstance = isInstance && "watch" in value; + + return isInstance; +} + +export function SystemConfigLibraryDtoFromJSON(json: any): SystemConfigLibraryDto { + return SystemConfigLibraryDtoFromJSONTyped(json, false); +} + +export function SystemConfigLibraryDtoFromJSONTyped(json: any, ignoreDiscriminator: boolean): SystemConfigLibraryDto { + if ((json === undefined) || (json === null)) { + return json; + } + return { + + 'scan': SystemConfigLibraryScanDtoFromJSON(json['scan']), + 'watch': SystemConfigLibraryWatchDtoFromJSON(json['watch']), + }; +} + +export function SystemConfigLibraryDtoToJSON(value?: SystemConfigLibraryDto | null): any { + if (value === undefined) { + return undefined; + } + if (value === null) { + return null; + } + return { + + 'scan': SystemConfigLibraryScanDtoToJSON(value.scan), + 'watch': SystemConfigLibraryWatchDtoToJSON(value.watch), + }; +} + diff --git a/open-api/typescript-sdk/fetch-client/models/SystemConfigLibraryScanDto.ts b/open-api/typescript-sdk/fetch-client/models/SystemConfigLibraryScanDto.ts new file mode 100644 index 0000000000..bd079fe202 --- /dev/null +++ b/open-api/typescript-sdk/fetch-client/models/SystemConfigLibraryScanDto.ts @@ -0,0 +1,75 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * Immich + * Immich API + * + * The version of the OpenAPI document: 1.94.1 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + +import { exists, mapValues } from '../runtime'; +/** + * + * @export + * @interface SystemConfigLibraryScanDto + */ +export interface SystemConfigLibraryScanDto { + /** + * + * @type {string} + * @memberof SystemConfigLibraryScanDto + */ + cronExpression: string; + /** + * + * @type {boolean} + * @memberof SystemConfigLibraryScanDto + */ + enabled: boolean; +} + +/** + * Check if a given object implements the SystemConfigLibraryScanDto interface. + */ +export function instanceOfSystemConfigLibraryScanDto(value: object): boolean { + let isInstance = true; + isInstance = isInstance && "cronExpression" in value; + isInstance = isInstance && "enabled" in value; + + return isInstance; +} + +export function SystemConfigLibraryScanDtoFromJSON(json: any): SystemConfigLibraryScanDto { + return SystemConfigLibraryScanDtoFromJSONTyped(json, false); +} + +export function SystemConfigLibraryScanDtoFromJSONTyped(json: any, ignoreDiscriminator: boolean): SystemConfigLibraryScanDto { + if ((json === undefined) || (json === null)) { + return json; + } + return { + + 'cronExpression': json['cronExpression'], + 'enabled': json['enabled'], + }; +} + +export function SystemConfigLibraryScanDtoToJSON(value?: SystemConfigLibraryScanDto | null): any { + if (value === undefined) { + return undefined; + } + if (value === null) { + return null; + } + return { + + 'cronExpression': value.cronExpression, + 'enabled': value.enabled, + }; +} + diff --git a/open-api/typescript-sdk/fetch-client/models/SystemConfigLibraryWatchDto.ts b/open-api/typescript-sdk/fetch-client/models/SystemConfigLibraryWatchDto.ts new file mode 100644 index 0000000000..3c69b99ed2 --- /dev/null +++ b/open-api/typescript-sdk/fetch-client/models/SystemConfigLibraryWatchDto.ts @@ -0,0 +1,84 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * Immich + * Immich API + * + * The version of the OpenAPI document: 1.94.1 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + +import { exists, mapValues } from '../runtime'; +/** + * + * @export + * @interface SystemConfigLibraryWatchDto + */ +export interface SystemConfigLibraryWatchDto { + /** + * + * @type {boolean} + * @memberof SystemConfigLibraryWatchDto + */ + enabled: boolean; + /** + * + * @type {number} + * @memberof SystemConfigLibraryWatchDto + */ + interval: number; + /** + * + * @type {boolean} + * @memberof SystemConfigLibraryWatchDto + */ + usePolling: boolean; +} + +/** + * Check if a given object implements the SystemConfigLibraryWatchDto interface. + */ +export function instanceOfSystemConfigLibraryWatchDto(value: object): boolean { + let isInstance = true; + isInstance = isInstance && "enabled" in value; + isInstance = isInstance && "interval" in value; + isInstance = isInstance && "usePolling" in value; + + return isInstance; +} + +export function SystemConfigLibraryWatchDtoFromJSON(json: any): SystemConfigLibraryWatchDto { + return SystemConfigLibraryWatchDtoFromJSONTyped(json, false); +} + +export function SystemConfigLibraryWatchDtoFromJSONTyped(json: any, ignoreDiscriminator: boolean): SystemConfigLibraryWatchDto { + if ((json === undefined) || (json === null)) { + return json; + } + return { + + 'enabled': json['enabled'], + 'interval': json['interval'], + 'usePolling': json['usePolling'], + }; +} + +export function SystemConfigLibraryWatchDtoToJSON(value?: SystemConfigLibraryWatchDto | null): any { + if (value === undefined) { + return undefined; + } + if (value === null) { + return null; + } + return { + + 'enabled': value.enabled, + 'interval': value.interval, + 'usePolling': value.usePolling, + }; +} + diff --git a/open-api/typescript-sdk/fetch-client/models/SystemConfigLoggingDto.ts b/open-api/typescript-sdk/fetch-client/models/SystemConfigLoggingDto.ts new file mode 100644 index 0000000000..5f9b4bc028 --- /dev/null +++ b/open-api/typescript-sdk/fetch-client/models/SystemConfigLoggingDto.ts @@ -0,0 +1,82 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * Immich + * Immich API + * + * The version of the OpenAPI document: 1.94.1 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + +import { exists, mapValues } from '../runtime'; +import type { LogLevel } from './LogLevel'; +import { + LogLevelFromJSON, + LogLevelFromJSONTyped, + LogLevelToJSON, +} from './LogLevel'; + +/** + * + * @export + * @interface SystemConfigLoggingDto + */ +export interface SystemConfigLoggingDto { + /** + * + * @type {boolean} + * @memberof SystemConfigLoggingDto + */ + enabled: boolean; + /** + * + * @type {LogLevel} + * @memberof SystemConfigLoggingDto + */ + level: LogLevel; +} + +/** + * Check if a given object implements the SystemConfigLoggingDto interface. + */ +export function instanceOfSystemConfigLoggingDto(value: object): boolean { + let isInstance = true; + isInstance = isInstance && "enabled" in value; + isInstance = isInstance && "level" in value; + + return isInstance; +} + +export function SystemConfigLoggingDtoFromJSON(json: any): SystemConfigLoggingDto { + return SystemConfigLoggingDtoFromJSONTyped(json, false); +} + +export function SystemConfigLoggingDtoFromJSONTyped(json: any, ignoreDiscriminator: boolean): SystemConfigLoggingDto { + if ((json === undefined) || (json === null)) { + return json; + } + return { + + 'enabled': json['enabled'], + 'level': LogLevelFromJSON(json['level']), + }; +} + +export function SystemConfigLoggingDtoToJSON(value?: SystemConfigLoggingDto | null): any { + if (value === undefined) { + return undefined; + } + if (value === null) { + return null; + } + return { + + 'enabled': value.enabled, + 'level': LogLevelToJSON(value.level), + }; +} + diff --git a/open-api/typescript-sdk/fetch-client/models/SystemConfigMachineLearningDto.ts b/open-api/typescript-sdk/fetch-client/models/SystemConfigMachineLearningDto.ts new file mode 100644 index 0000000000..16acca93d4 --- /dev/null +++ b/open-api/typescript-sdk/fetch-client/models/SystemConfigMachineLearningDto.ts @@ -0,0 +1,106 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * Immich + * Immich API + * + * The version of the OpenAPI document: 1.94.1 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + +import { exists, mapValues } from '../runtime'; +import type { CLIPConfig } from './CLIPConfig'; +import { + CLIPConfigFromJSON, + CLIPConfigFromJSONTyped, + CLIPConfigToJSON, +} from './CLIPConfig'; +import type { RecognitionConfig } from './RecognitionConfig'; +import { + RecognitionConfigFromJSON, + RecognitionConfigFromJSONTyped, + RecognitionConfigToJSON, +} from './RecognitionConfig'; + +/** + * + * @export + * @interface SystemConfigMachineLearningDto + */ +export interface SystemConfigMachineLearningDto { + /** + * + * @type {CLIPConfig} + * @memberof SystemConfigMachineLearningDto + */ + clip: CLIPConfig; + /** + * + * @type {boolean} + * @memberof SystemConfigMachineLearningDto + */ + enabled: boolean; + /** + * + * @type {RecognitionConfig} + * @memberof SystemConfigMachineLearningDto + */ + facialRecognition: RecognitionConfig; + /** + * + * @type {string} + * @memberof SystemConfigMachineLearningDto + */ + url: string; +} + +/** + * Check if a given object implements the SystemConfigMachineLearningDto interface. + */ +export function instanceOfSystemConfigMachineLearningDto(value: object): boolean { + let isInstance = true; + isInstance = isInstance && "clip" in value; + isInstance = isInstance && "enabled" in value; + isInstance = isInstance && "facialRecognition" in value; + isInstance = isInstance && "url" in value; + + return isInstance; +} + +export function SystemConfigMachineLearningDtoFromJSON(json: any): SystemConfigMachineLearningDto { + return SystemConfigMachineLearningDtoFromJSONTyped(json, false); +} + +export function SystemConfigMachineLearningDtoFromJSONTyped(json: any, ignoreDiscriminator: boolean): SystemConfigMachineLearningDto { + if ((json === undefined) || (json === null)) { + return json; + } + return { + + 'clip': CLIPConfigFromJSON(json['clip']), + 'enabled': json['enabled'], + 'facialRecognition': RecognitionConfigFromJSON(json['facialRecognition']), + 'url': json['url'], + }; +} + +export function SystemConfigMachineLearningDtoToJSON(value?: SystemConfigMachineLearningDto | null): any { + if (value === undefined) { + return undefined; + } + if (value === null) { + return null; + } + return { + + 'clip': CLIPConfigToJSON(value.clip), + 'enabled': value.enabled, + 'facialRecognition': RecognitionConfigToJSON(value.facialRecognition), + 'url': value.url, + }; +} + diff --git a/open-api/typescript-sdk/fetch-client/models/SystemConfigMapDto.ts b/open-api/typescript-sdk/fetch-client/models/SystemConfigMapDto.ts new file mode 100644 index 0000000000..0691fdafa5 --- /dev/null +++ b/open-api/typescript-sdk/fetch-client/models/SystemConfigMapDto.ts @@ -0,0 +1,84 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * Immich + * Immich API + * + * The version of the OpenAPI document: 1.94.1 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + +import { exists, mapValues } from '../runtime'; +/** + * + * @export + * @interface SystemConfigMapDto + */ +export interface SystemConfigMapDto { + /** + * + * @type {string} + * @memberof SystemConfigMapDto + */ + darkStyle: string; + /** + * + * @type {boolean} + * @memberof SystemConfigMapDto + */ + enabled: boolean; + /** + * + * @type {string} + * @memberof SystemConfigMapDto + */ + lightStyle: string; +} + +/** + * Check if a given object implements the SystemConfigMapDto interface. + */ +export function instanceOfSystemConfigMapDto(value: object): boolean { + let isInstance = true; + isInstance = isInstance && "darkStyle" in value; + isInstance = isInstance && "enabled" in value; + isInstance = isInstance && "lightStyle" in value; + + return isInstance; +} + +export function SystemConfigMapDtoFromJSON(json: any): SystemConfigMapDto { + return SystemConfigMapDtoFromJSONTyped(json, false); +} + +export function SystemConfigMapDtoFromJSONTyped(json: any, ignoreDiscriminator: boolean): SystemConfigMapDto { + if ((json === undefined) || (json === null)) { + return json; + } + return { + + 'darkStyle': json['darkStyle'], + 'enabled': json['enabled'], + 'lightStyle': json['lightStyle'], + }; +} + +export function SystemConfigMapDtoToJSON(value?: SystemConfigMapDto | null): any { + if (value === undefined) { + return undefined; + } + if (value === null) { + return null; + } + return { + + 'darkStyle': value.darkStyle, + 'enabled': value.enabled, + 'lightStyle': value.lightStyle, + }; +} + diff --git a/open-api/typescript-sdk/fetch-client/models/SystemConfigNewVersionCheckDto.ts b/open-api/typescript-sdk/fetch-client/models/SystemConfigNewVersionCheckDto.ts new file mode 100644 index 0000000000..c8a4e5edb0 --- /dev/null +++ b/open-api/typescript-sdk/fetch-client/models/SystemConfigNewVersionCheckDto.ts @@ -0,0 +1,66 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * Immich + * Immich API + * + * The version of the OpenAPI document: 1.94.1 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + +import { exists, mapValues } from '../runtime'; +/** + * + * @export + * @interface SystemConfigNewVersionCheckDto + */ +export interface SystemConfigNewVersionCheckDto { + /** + * + * @type {boolean} + * @memberof SystemConfigNewVersionCheckDto + */ + enabled: boolean; +} + +/** + * Check if a given object implements the SystemConfigNewVersionCheckDto interface. + */ +export function instanceOfSystemConfigNewVersionCheckDto(value: object): boolean { + let isInstance = true; + isInstance = isInstance && "enabled" in value; + + return isInstance; +} + +export function SystemConfigNewVersionCheckDtoFromJSON(json: any): SystemConfigNewVersionCheckDto { + return SystemConfigNewVersionCheckDtoFromJSONTyped(json, false); +} + +export function SystemConfigNewVersionCheckDtoFromJSONTyped(json: any, ignoreDiscriminator: boolean): SystemConfigNewVersionCheckDto { + if ((json === undefined) || (json === null)) { + return json; + } + return { + + 'enabled': json['enabled'], + }; +} + +export function SystemConfigNewVersionCheckDtoToJSON(value?: SystemConfigNewVersionCheckDto | null): any { + if (value === undefined) { + return undefined; + } + if (value === null) { + return null; + } + return { + + 'enabled': value.enabled, + }; +} + diff --git a/open-api/typescript-sdk/fetch-client/models/SystemConfigOAuthDto.ts b/open-api/typescript-sdk/fetch-client/models/SystemConfigOAuthDto.ts new file mode 100644 index 0000000000..784d229eef --- /dev/null +++ b/open-api/typescript-sdk/fetch-client/models/SystemConfigOAuthDto.ts @@ -0,0 +1,165 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * Immich + * Immich API + * + * The version of the OpenAPI document: 1.94.1 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + +import { exists, mapValues } from '../runtime'; +/** + * + * @export + * @interface SystemConfigOAuthDto + */ +export interface SystemConfigOAuthDto { + /** + * + * @type {boolean} + * @memberof SystemConfigOAuthDto + */ + autoLaunch: boolean; + /** + * + * @type {boolean} + * @memberof SystemConfigOAuthDto + */ + autoRegister: boolean; + /** + * + * @type {string} + * @memberof SystemConfigOAuthDto + */ + buttonText: string; + /** + * + * @type {string} + * @memberof SystemConfigOAuthDto + */ + clientId: string; + /** + * + * @type {string} + * @memberof SystemConfigOAuthDto + */ + clientSecret: string; + /** + * + * @type {boolean} + * @memberof SystemConfigOAuthDto + */ + enabled: boolean; + /** + * + * @type {string} + * @memberof SystemConfigOAuthDto + */ + issuerUrl: string; + /** + * + * @type {boolean} + * @memberof SystemConfigOAuthDto + */ + mobileOverrideEnabled: boolean; + /** + * + * @type {string} + * @memberof SystemConfigOAuthDto + */ + mobileRedirectUri: string; + /** + * + * @type {string} + * @memberof SystemConfigOAuthDto + */ + scope: string; + /** + * + * @type {string} + * @memberof SystemConfigOAuthDto + */ + signingAlgorithm: string; + /** + * + * @type {string} + * @memberof SystemConfigOAuthDto + */ + storageLabelClaim: string; +} + +/** + * Check if a given object implements the SystemConfigOAuthDto interface. + */ +export function instanceOfSystemConfigOAuthDto(value: object): boolean { + let isInstance = true; + isInstance = isInstance && "autoLaunch" in value; + isInstance = isInstance && "autoRegister" in value; + isInstance = isInstance && "buttonText" in value; + isInstance = isInstance && "clientId" in value; + isInstance = isInstance && "clientSecret" in value; + isInstance = isInstance && "enabled" in value; + isInstance = isInstance && "issuerUrl" in value; + isInstance = isInstance && "mobileOverrideEnabled" in value; + isInstance = isInstance && "mobileRedirectUri" in value; + isInstance = isInstance && "scope" in value; + isInstance = isInstance && "signingAlgorithm" in value; + isInstance = isInstance && "storageLabelClaim" in value; + + return isInstance; +} + +export function SystemConfigOAuthDtoFromJSON(json: any): SystemConfigOAuthDto { + return SystemConfigOAuthDtoFromJSONTyped(json, false); +} + +export function SystemConfigOAuthDtoFromJSONTyped(json: any, ignoreDiscriminator: boolean): SystemConfigOAuthDto { + if ((json === undefined) || (json === null)) { + return json; + } + return { + + 'autoLaunch': json['autoLaunch'], + 'autoRegister': json['autoRegister'], + 'buttonText': json['buttonText'], + 'clientId': json['clientId'], + 'clientSecret': json['clientSecret'], + 'enabled': json['enabled'], + 'issuerUrl': json['issuerUrl'], + 'mobileOverrideEnabled': json['mobileOverrideEnabled'], + 'mobileRedirectUri': json['mobileRedirectUri'], + 'scope': json['scope'], + 'signingAlgorithm': json['signingAlgorithm'], + 'storageLabelClaim': json['storageLabelClaim'], + }; +} + +export function SystemConfigOAuthDtoToJSON(value?: SystemConfigOAuthDto | null): any { + if (value === undefined) { + return undefined; + } + if (value === null) { + return null; + } + return { + + 'autoLaunch': value.autoLaunch, + 'autoRegister': value.autoRegister, + 'buttonText': value.buttonText, + 'clientId': value.clientId, + 'clientSecret': value.clientSecret, + 'enabled': value.enabled, + 'issuerUrl': value.issuerUrl, + 'mobileOverrideEnabled': value.mobileOverrideEnabled, + 'mobileRedirectUri': value.mobileRedirectUri, + 'scope': value.scope, + 'signingAlgorithm': value.signingAlgorithm, + 'storageLabelClaim': value.storageLabelClaim, + }; +} + diff --git a/open-api/typescript-sdk/fetch-client/models/SystemConfigPasswordLoginDto.ts b/open-api/typescript-sdk/fetch-client/models/SystemConfigPasswordLoginDto.ts new file mode 100644 index 0000000000..2e76b27a9e --- /dev/null +++ b/open-api/typescript-sdk/fetch-client/models/SystemConfigPasswordLoginDto.ts @@ -0,0 +1,66 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * Immich + * Immich API + * + * The version of the OpenAPI document: 1.94.1 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + +import { exists, mapValues } from '../runtime'; +/** + * + * @export + * @interface SystemConfigPasswordLoginDto + */ +export interface SystemConfigPasswordLoginDto { + /** + * + * @type {boolean} + * @memberof SystemConfigPasswordLoginDto + */ + enabled: boolean; +} + +/** + * Check if a given object implements the SystemConfigPasswordLoginDto interface. + */ +export function instanceOfSystemConfigPasswordLoginDto(value: object): boolean { + let isInstance = true; + isInstance = isInstance && "enabled" in value; + + return isInstance; +} + +export function SystemConfigPasswordLoginDtoFromJSON(json: any): SystemConfigPasswordLoginDto { + return SystemConfigPasswordLoginDtoFromJSONTyped(json, false); +} + +export function SystemConfigPasswordLoginDtoFromJSONTyped(json: any, ignoreDiscriminator: boolean): SystemConfigPasswordLoginDto { + if ((json === undefined) || (json === null)) { + return json; + } + return { + + 'enabled': json['enabled'], + }; +} + +export function SystemConfigPasswordLoginDtoToJSON(value?: SystemConfigPasswordLoginDto | null): any { + if (value === undefined) { + return undefined; + } + if (value === null) { + return null; + } + return { + + 'enabled': value.enabled, + }; +} + diff --git a/open-api/typescript-sdk/fetch-client/models/SystemConfigReverseGeocodingDto.ts b/open-api/typescript-sdk/fetch-client/models/SystemConfigReverseGeocodingDto.ts new file mode 100644 index 0000000000..95928108f6 --- /dev/null +++ b/open-api/typescript-sdk/fetch-client/models/SystemConfigReverseGeocodingDto.ts @@ -0,0 +1,66 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * Immich + * Immich API + * + * The version of the OpenAPI document: 1.94.1 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + +import { exists, mapValues } from '../runtime'; +/** + * + * @export + * @interface SystemConfigReverseGeocodingDto + */ +export interface SystemConfigReverseGeocodingDto { + /** + * + * @type {boolean} + * @memberof SystemConfigReverseGeocodingDto + */ + enabled: boolean; +} + +/** + * Check if a given object implements the SystemConfigReverseGeocodingDto interface. + */ +export function instanceOfSystemConfigReverseGeocodingDto(value: object): boolean { + let isInstance = true; + isInstance = isInstance && "enabled" in value; + + return isInstance; +} + +export function SystemConfigReverseGeocodingDtoFromJSON(json: any): SystemConfigReverseGeocodingDto { + return SystemConfigReverseGeocodingDtoFromJSONTyped(json, false); +} + +export function SystemConfigReverseGeocodingDtoFromJSONTyped(json: any, ignoreDiscriminator: boolean): SystemConfigReverseGeocodingDto { + if ((json === undefined) || (json === null)) { + return json; + } + return { + + 'enabled': json['enabled'], + }; +} + +export function SystemConfigReverseGeocodingDtoToJSON(value?: SystemConfigReverseGeocodingDto | null): any { + if (value === undefined) { + return undefined; + } + if (value === null) { + return null; + } + return { + + 'enabled': value.enabled, + }; +} + diff --git a/open-api/typescript-sdk/fetch-client/models/SystemConfigServerDto.ts b/open-api/typescript-sdk/fetch-client/models/SystemConfigServerDto.ts new file mode 100644 index 0000000000..ec54fa36d1 --- /dev/null +++ b/open-api/typescript-sdk/fetch-client/models/SystemConfigServerDto.ts @@ -0,0 +1,75 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * Immich + * Immich API + * + * The version of the OpenAPI document: 1.94.1 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + +import { exists, mapValues } from '../runtime'; +/** + * + * @export + * @interface SystemConfigServerDto + */ +export interface SystemConfigServerDto { + /** + * + * @type {string} + * @memberof SystemConfigServerDto + */ + externalDomain: string; + /** + * + * @type {string} + * @memberof SystemConfigServerDto + */ + loginPageMessage: string; +} + +/** + * Check if a given object implements the SystemConfigServerDto interface. + */ +export function instanceOfSystemConfigServerDto(value: object): boolean { + let isInstance = true; + isInstance = isInstance && "externalDomain" in value; + isInstance = isInstance && "loginPageMessage" in value; + + return isInstance; +} + +export function SystemConfigServerDtoFromJSON(json: any): SystemConfigServerDto { + return SystemConfigServerDtoFromJSONTyped(json, false); +} + +export function SystemConfigServerDtoFromJSONTyped(json: any, ignoreDiscriminator: boolean): SystemConfigServerDto { + if ((json === undefined) || (json === null)) { + return json; + } + return { + + 'externalDomain': json['externalDomain'], + 'loginPageMessage': json['loginPageMessage'], + }; +} + +export function SystemConfigServerDtoToJSON(value?: SystemConfigServerDto | null): any { + if (value === undefined) { + return undefined; + } + if (value === null) { + return null; + } + return { + + 'externalDomain': value.externalDomain, + 'loginPageMessage': value.loginPageMessage, + }; +} + diff --git a/open-api/typescript-sdk/fetch-client/models/SystemConfigStorageTemplateDto.ts b/open-api/typescript-sdk/fetch-client/models/SystemConfigStorageTemplateDto.ts new file mode 100644 index 0000000000..b55172ceb6 --- /dev/null +++ b/open-api/typescript-sdk/fetch-client/models/SystemConfigStorageTemplateDto.ts @@ -0,0 +1,84 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * Immich + * Immich API + * + * The version of the OpenAPI document: 1.94.1 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + +import { exists, mapValues } from '../runtime'; +/** + * + * @export + * @interface SystemConfigStorageTemplateDto + */ +export interface SystemConfigStorageTemplateDto { + /** + * + * @type {boolean} + * @memberof SystemConfigStorageTemplateDto + */ + enabled: boolean; + /** + * + * @type {boolean} + * @memberof SystemConfigStorageTemplateDto + */ + hashVerificationEnabled: boolean; + /** + * + * @type {string} + * @memberof SystemConfigStorageTemplateDto + */ + template: string; +} + +/** + * Check if a given object implements the SystemConfigStorageTemplateDto interface. + */ +export function instanceOfSystemConfigStorageTemplateDto(value: object): boolean { + let isInstance = true; + isInstance = isInstance && "enabled" in value; + isInstance = isInstance && "hashVerificationEnabled" in value; + isInstance = isInstance && "template" in value; + + return isInstance; +} + +export function SystemConfigStorageTemplateDtoFromJSON(json: any): SystemConfigStorageTemplateDto { + return SystemConfigStorageTemplateDtoFromJSONTyped(json, false); +} + +export function SystemConfigStorageTemplateDtoFromJSONTyped(json: any, ignoreDiscriminator: boolean): SystemConfigStorageTemplateDto { + if ((json === undefined) || (json === null)) { + return json; + } + return { + + 'enabled': json['enabled'], + 'hashVerificationEnabled': json['hashVerificationEnabled'], + 'template': json['template'], + }; +} + +export function SystemConfigStorageTemplateDtoToJSON(value?: SystemConfigStorageTemplateDto | null): any { + if (value === undefined) { + return undefined; + } + if (value === null) { + return null; + } + return { + + 'enabled': value.enabled, + 'hashVerificationEnabled': value.hashVerificationEnabled, + 'template': value.template, + }; +} + diff --git a/open-api/typescript-sdk/fetch-client/models/SystemConfigTemplateStorageOptionDto.ts b/open-api/typescript-sdk/fetch-client/models/SystemConfigTemplateStorageOptionDto.ts new file mode 100644 index 0000000000..f38d86a000 --- /dev/null +++ b/open-api/typescript-sdk/fetch-client/models/SystemConfigTemplateStorageOptionDto.ts @@ -0,0 +1,129 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * Immich + * Immich API + * + * The version of the OpenAPI document: 1.94.1 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + +import { exists, mapValues } from '../runtime'; +/** + * + * @export + * @interface SystemConfigTemplateStorageOptionDto + */ +export interface SystemConfigTemplateStorageOptionDto { + /** + * + * @type {Array} + * @memberof SystemConfigTemplateStorageOptionDto + */ + dayOptions: Array; + /** + * + * @type {Array} + * @memberof SystemConfigTemplateStorageOptionDto + */ + hourOptions: Array; + /** + * + * @type {Array} + * @memberof SystemConfigTemplateStorageOptionDto + */ + minuteOptions: Array; + /** + * + * @type {Array} + * @memberof SystemConfigTemplateStorageOptionDto + */ + monthOptions: Array; + /** + * + * @type {Array} + * @memberof SystemConfigTemplateStorageOptionDto + */ + presetOptions: Array; + /** + * + * @type {Array} + * @memberof SystemConfigTemplateStorageOptionDto + */ + secondOptions: Array; + /** + * + * @type {Array} + * @memberof SystemConfigTemplateStorageOptionDto + */ + weekOptions: Array; + /** + * + * @type {Array} + * @memberof SystemConfigTemplateStorageOptionDto + */ + yearOptions: Array; +} + +/** + * Check if a given object implements the SystemConfigTemplateStorageOptionDto interface. + */ +export function instanceOfSystemConfigTemplateStorageOptionDto(value: object): boolean { + let isInstance = true; + isInstance = isInstance && "dayOptions" in value; + isInstance = isInstance && "hourOptions" in value; + isInstance = isInstance && "minuteOptions" in value; + isInstance = isInstance && "monthOptions" in value; + isInstance = isInstance && "presetOptions" in value; + isInstance = isInstance && "secondOptions" in value; + isInstance = isInstance && "weekOptions" in value; + isInstance = isInstance && "yearOptions" in value; + + return isInstance; +} + +export function SystemConfigTemplateStorageOptionDtoFromJSON(json: any): SystemConfigTemplateStorageOptionDto { + return SystemConfigTemplateStorageOptionDtoFromJSONTyped(json, false); +} + +export function SystemConfigTemplateStorageOptionDtoFromJSONTyped(json: any, ignoreDiscriminator: boolean): SystemConfigTemplateStorageOptionDto { + if ((json === undefined) || (json === null)) { + return json; + } + return { + + 'dayOptions': json['dayOptions'], + 'hourOptions': json['hourOptions'], + 'minuteOptions': json['minuteOptions'], + 'monthOptions': json['monthOptions'], + 'presetOptions': json['presetOptions'], + 'secondOptions': json['secondOptions'], + 'weekOptions': json['weekOptions'], + 'yearOptions': json['yearOptions'], + }; +} + +export function SystemConfigTemplateStorageOptionDtoToJSON(value?: SystemConfigTemplateStorageOptionDto | null): any { + if (value === undefined) { + return undefined; + } + if (value === null) { + return null; + } + return { + + 'dayOptions': value.dayOptions, + 'hourOptions': value.hourOptions, + 'minuteOptions': value.minuteOptions, + 'monthOptions': value.monthOptions, + 'presetOptions': value.presetOptions, + 'secondOptions': value.secondOptions, + 'weekOptions': value.weekOptions, + 'yearOptions': value.yearOptions, + }; +} + diff --git a/open-api/typescript-sdk/fetch-client/models/SystemConfigThemeDto.ts b/open-api/typescript-sdk/fetch-client/models/SystemConfigThemeDto.ts new file mode 100644 index 0000000000..73ec8ea633 --- /dev/null +++ b/open-api/typescript-sdk/fetch-client/models/SystemConfigThemeDto.ts @@ -0,0 +1,66 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * Immich + * Immich API + * + * The version of the OpenAPI document: 1.94.1 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + +import { exists, mapValues } from '../runtime'; +/** + * + * @export + * @interface SystemConfigThemeDto + */ +export interface SystemConfigThemeDto { + /** + * + * @type {string} + * @memberof SystemConfigThemeDto + */ + customCss: string; +} + +/** + * Check if a given object implements the SystemConfigThemeDto interface. + */ +export function instanceOfSystemConfigThemeDto(value: object): boolean { + let isInstance = true; + isInstance = isInstance && "customCss" in value; + + return isInstance; +} + +export function SystemConfigThemeDtoFromJSON(json: any): SystemConfigThemeDto { + return SystemConfigThemeDtoFromJSONTyped(json, false); +} + +export function SystemConfigThemeDtoFromJSONTyped(json: any, ignoreDiscriminator: boolean): SystemConfigThemeDto { + if ((json === undefined) || (json === null)) { + return json; + } + return { + + 'customCss': json['customCss'], + }; +} + +export function SystemConfigThemeDtoToJSON(value?: SystemConfigThemeDto | null): any { + if (value === undefined) { + return undefined; + } + if (value === null) { + return null; + } + return { + + 'customCss': value.customCss, + }; +} + diff --git a/open-api/typescript-sdk/fetch-client/models/SystemConfigThumbnailDto.ts b/open-api/typescript-sdk/fetch-client/models/SystemConfigThumbnailDto.ts new file mode 100644 index 0000000000..c2f32782c4 --- /dev/null +++ b/open-api/typescript-sdk/fetch-client/models/SystemConfigThumbnailDto.ts @@ -0,0 +1,100 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * Immich + * Immich API + * + * The version of the OpenAPI document: 1.94.1 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + +import { exists, mapValues } from '../runtime'; +import type { Colorspace } from './Colorspace'; +import { + ColorspaceFromJSON, + ColorspaceFromJSONTyped, + ColorspaceToJSON, +} from './Colorspace'; + +/** + * + * @export + * @interface SystemConfigThumbnailDto + */ +export interface SystemConfigThumbnailDto { + /** + * + * @type {Colorspace} + * @memberof SystemConfigThumbnailDto + */ + colorspace: Colorspace; + /** + * + * @type {number} + * @memberof SystemConfigThumbnailDto + */ + jpegSize: number; + /** + * + * @type {number} + * @memberof SystemConfigThumbnailDto + */ + quality: number; + /** + * + * @type {number} + * @memberof SystemConfigThumbnailDto + */ + webpSize: number; +} + +/** + * Check if a given object implements the SystemConfigThumbnailDto interface. + */ +export function instanceOfSystemConfigThumbnailDto(value: object): boolean { + let isInstance = true; + isInstance = isInstance && "colorspace" in value; + isInstance = isInstance && "jpegSize" in value; + isInstance = isInstance && "quality" in value; + isInstance = isInstance && "webpSize" in value; + + return isInstance; +} + +export function SystemConfigThumbnailDtoFromJSON(json: any): SystemConfigThumbnailDto { + return SystemConfigThumbnailDtoFromJSONTyped(json, false); +} + +export function SystemConfigThumbnailDtoFromJSONTyped(json: any, ignoreDiscriminator: boolean): SystemConfigThumbnailDto { + if ((json === undefined) || (json === null)) { + return json; + } + return { + + 'colorspace': ColorspaceFromJSON(json['colorspace']), + 'jpegSize': json['jpegSize'], + 'quality': json['quality'], + 'webpSize': json['webpSize'], + }; +} + +export function SystemConfigThumbnailDtoToJSON(value?: SystemConfigThumbnailDto | null): any { + if (value === undefined) { + return undefined; + } + if (value === null) { + return null; + } + return { + + 'colorspace': ColorspaceToJSON(value.colorspace), + 'jpegSize': value.jpegSize, + 'quality': value.quality, + 'webpSize': value.webpSize, + }; +} + diff --git a/open-api/typescript-sdk/fetch-client/models/SystemConfigTrashDto.ts b/open-api/typescript-sdk/fetch-client/models/SystemConfigTrashDto.ts new file mode 100644 index 0000000000..704ae17e2f --- /dev/null +++ b/open-api/typescript-sdk/fetch-client/models/SystemConfigTrashDto.ts @@ -0,0 +1,75 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * Immich + * Immich API + * + * The version of the OpenAPI document: 1.94.1 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + +import { exists, mapValues } from '../runtime'; +/** + * + * @export + * @interface SystemConfigTrashDto + */ +export interface SystemConfigTrashDto { + /** + * + * @type {number} + * @memberof SystemConfigTrashDto + */ + days: number; + /** + * + * @type {boolean} + * @memberof SystemConfigTrashDto + */ + enabled: boolean; +} + +/** + * Check if a given object implements the SystemConfigTrashDto interface. + */ +export function instanceOfSystemConfigTrashDto(value: object): boolean { + let isInstance = true; + isInstance = isInstance && "days" in value; + isInstance = isInstance && "enabled" in value; + + return isInstance; +} + +export function SystemConfigTrashDtoFromJSON(json: any): SystemConfigTrashDto { + return SystemConfigTrashDtoFromJSONTyped(json, false); +} + +export function SystemConfigTrashDtoFromJSONTyped(json: any, ignoreDiscriminator: boolean): SystemConfigTrashDto { + if ((json === undefined) || (json === null)) { + return json; + } + return { + + 'days': json['days'], + 'enabled': json['enabled'], + }; +} + +export function SystemConfigTrashDtoToJSON(value?: SystemConfigTrashDto | null): any { + if (value === undefined) { + return undefined; + } + if (value === null) { + return null; + } + return { + + 'days': value.days, + 'enabled': value.enabled, + }; +} + diff --git a/open-api/typescript-sdk/fetch-client/models/TagResponseDto.ts b/open-api/typescript-sdk/fetch-client/models/TagResponseDto.ts new file mode 100644 index 0000000000..9cada1cecc --- /dev/null +++ b/open-api/typescript-sdk/fetch-client/models/TagResponseDto.ts @@ -0,0 +1,100 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * Immich + * Immich API + * + * The version of the OpenAPI document: 1.94.1 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + +import { exists, mapValues } from '../runtime'; +import type { TagTypeEnum } from './TagTypeEnum'; +import { + TagTypeEnumFromJSON, + TagTypeEnumFromJSONTyped, + TagTypeEnumToJSON, +} from './TagTypeEnum'; + +/** + * + * @export + * @interface TagResponseDto + */ +export interface TagResponseDto { + /** + * + * @type {string} + * @memberof TagResponseDto + */ + id: string; + /** + * + * @type {string} + * @memberof TagResponseDto + */ + name: string; + /** + * + * @type {TagTypeEnum} + * @memberof TagResponseDto + */ + type: TagTypeEnum; + /** + * + * @type {string} + * @memberof TagResponseDto + */ + userId: string; +} + +/** + * Check if a given object implements the TagResponseDto interface. + */ +export function instanceOfTagResponseDto(value: object): boolean { + let isInstance = true; + isInstance = isInstance && "id" in value; + isInstance = isInstance && "name" in value; + isInstance = isInstance && "type" in value; + isInstance = isInstance && "userId" in value; + + return isInstance; +} + +export function TagResponseDtoFromJSON(json: any): TagResponseDto { + return TagResponseDtoFromJSONTyped(json, false); +} + +export function TagResponseDtoFromJSONTyped(json: any, ignoreDiscriminator: boolean): TagResponseDto { + if ((json === undefined) || (json === null)) { + return json; + } + return { + + 'id': json['id'], + 'name': json['name'], + 'type': TagTypeEnumFromJSON(json['type']), + 'userId': json['userId'], + }; +} + +export function TagResponseDtoToJSON(value?: TagResponseDto | null): any { + if (value === undefined) { + return undefined; + } + if (value === null) { + return null; + } + return { + + 'id': value.id, + 'name': value.name, + 'type': TagTypeEnumToJSON(value.type), + 'userId': value.userId, + }; +} + diff --git a/open-api/typescript-sdk/fetch-client/models/TagTypeEnum.ts b/open-api/typescript-sdk/fetch-client/models/TagTypeEnum.ts new file mode 100644 index 0000000000..e2677cb88b --- /dev/null +++ b/open-api/typescript-sdk/fetch-client/models/TagTypeEnum.ts @@ -0,0 +1,39 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * Immich + * Immich API + * + * The version of the OpenAPI document: 1.94.1 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + + +/** + * + * @export + */ +export const TagTypeEnum = { + Object: 'OBJECT', + Face: 'FACE', + Custom: 'CUSTOM' +} as const; +export type TagTypeEnum = typeof TagTypeEnum[keyof typeof TagTypeEnum]; + + +export function TagTypeEnumFromJSON(json: any): TagTypeEnum { + return TagTypeEnumFromJSONTyped(json, false); +} + +export function TagTypeEnumFromJSONTyped(json: any, ignoreDiscriminator: boolean): TagTypeEnum { + return json as TagTypeEnum; +} + +export function TagTypeEnumToJSON(value?: TagTypeEnum | null): any { + return value as any; +} + diff --git a/open-api/typescript-sdk/fetch-client/models/ThumbnailFormat.ts b/open-api/typescript-sdk/fetch-client/models/ThumbnailFormat.ts new file mode 100644 index 0000000000..653f0f6a97 --- /dev/null +++ b/open-api/typescript-sdk/fetch-client/models/ThumbnailFormat.ts @@ -0,0 +1,38 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * Immich + * Immich API + * + * The version of the OpenAPI document: 1.94.1 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + + +/** + * + * @export + */ +export const ThumbnailFormat = { + Jpeg: 'JPEG', + Webp: 'WEBP' +} as const; +export type ThumbnailFormat = typeof ThumbnailFormat[keyof typeof ThumbnailFormat]; + + +export function ThumbnailFormatFromJSON(json: any): ThumbnailFormat { + return ThumbnailFormatFromJSONTyped(json, false); +} + +export function ThumbnailFormatFromJSONTyped(json: any, ignoreDiscriminator: boolean): ThumbnailFormat { + return json as ThumbnailFormat; +} + +export function ThumbnailFormatToJSON(value?: ThumbnailFormat | null): any { + return value as any; +} + diff --git a/open-api/typescript-sdk/fetch-client/models/TimeBucketResponseDto.ts b/open-api/typescript-sdk/fetch-client/models/TimeBucketResponseDto.ts new file mode 100644 index 0000000000..325691f47e --- /dev/null +++ b/open-api/typescript-sdk/fetch-client/models/TimeBucketResponseDto.ts @@ -0,0 +1,75 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * Immich + * Immich API + * + * The version of the OpenAPI document: 1.94.1 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + +import { exists, mapValues } from '../runtime'; +/** + * + * @export + * @interface TimeBucketResponseDto + */ +export interface TimeBucketResponseDto { + /** + * + * @type {number} + * @memberof TimeBucketResponseDto + */ + count: number; + /** + * + * @type {string} + * @memberof TimeBucketResponseDto + */ + timeBucket: string; +} + +/** + * Check if a given object implements the TimeBucketResponseDto interface. + */ +export function instanceOfTimeBucketResponseDto(value: object): boolean { + let isInstance = true; + isInstance = isInstance && "count" in value; + isInstance = isInstance && "timeBucket" in value; + + return isInstance; +} + +export function TimeBucketResponseDtoFromJSON(json: any): TimeBucketResponseDto { + return TimeBucketResponseDtoFromJSONTyped(json, false); +} + +export function TimeBucketResponseDtoFromJSONTyped(json: any, ignoreDiscriminator: boolean): TimeBucketResponseDto { + if ((json === undefined) || (json === null)) { + return json; + } + return { + + 'count': json['count'], + 'timeBucket': json['timeBucket'], + }; +} + +export function TimeBucketResponseDtoToJSON(value?: TimeBucketResponseDto | null): any { + if (value === undefined) { + return undefined; + } + if (value === null) { + return null; + } + return { + + 'count': value.count, + 'timeBucket': value.timeBucket, + }; +} + diff --git a/open-api/typescript-sdk/fetch-client/models/TimeBucketSize.ts b/open-api/typescript-sdk/fetch-client/models/TimeBucketSize.ts new file mode 100644 index 0000000000..d21da0cf1b --- /dev/null +++ b/open-api/typescript-sdk/fetch-client/models/TimeBucketSize.ts @@ -0,0 +1,38 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * Immich + * Immich API + * + * The version of the OpenAPI document: 1.94.1 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + + +/** + * + * @export + */ +export const TimeBucketSize = { + Day: 'DAY', + Month: 'MONTH' +} as const; +export type TimeBucketSize = typeof TimeBucketSize[keyof typeof TimeBucketSize]; + + +export function TimeBucketSizeFromJSON(json: any): TimeBucketSize { + return TimeBucketSizeFromJSONTyped(json, false); +} + +export function TimeBucketSizeFromJSONTyped(json: any, ignoreDiscriminator: boolean): TimeBucketSize { + return json as TimeBucketSize; +} + +export function TimeBucketSizeToJSON(value?: TimeBucketSize | null): any { + return value as any; +} + diff --git a/open-api/typescript-sdk/fetch-client/models/ToneMapping.ts b/open-api/typescript-sdk/fetch-client/models/ToneMapping.ts new file mode 100644 index 0000000000..48a42cd328 --- /dev/null +++ b/open-api/typescript-sdk/fetch-client/models/ToneMapping.ts @@ -0,0 +1,40 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * Immich + * Immich API + * + * The version of the OpenAPI document: 1.94.1 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + + +/** + * + * @export + */ +export const ToneMapping = { + Hable: 'hable', + Mobius: 'mobius', + Reinhard: 'reinhard', + Disabled: 'disabled' +} as const; +export type ToneMapping = typeof ToneMapping[keyof typeof ToneMapping]; + + +export function ToneMappingFromJSON(json: any): ToneMapping { + return ToneMappingFromJSONTyped(json, false); +} + +export function ToneMappingFromJSONTyped(json: any, ignoreDiscriminator: boolean): ToneMapping { + return json as ToneMapping; +} + +export function ToneMappingToJSON(value?: ToneMapping | null): any { + return value as any; +} + diff --git a/open-api/typescript-sdk/fetch-client/models/TranscodeHWAccel.ts b/open-api/typescript-sdk/fetch-client/models/TranscodeHWAccel.ts new file mode 100644 index 0000000000..7de80988da --- /dev/null +++ b/open-api/typescript-sdk/fetch-client/models/TranscodeHWAccel.ts @@ -0,0 +1,41 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * Immich + * Immich API + * + * The version of the OpenAPI document: 1.94.1 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + + +/** + * + * @export + */ +export const TranscodeHWAccel = { + Nvenc: 'nvenc', + Qsv: 'qsv', + Vaapi: 'vaapi', + Rkmpp: 'rkmpp', + Disabled: 'disabled' +} as const; +export type TranscodeHWAccel = typeof TranscodeHWAccel[keyof typeof TranscodeHWAccel]; + + +export function TranscodeHWAccelFromJSON(json: any): TranscodeHWAccel { + return TranscodeHWAccelFromJSONTyped(json, false); +} + +export function TranscodeHWAccelFromJSONTyped(json: any, ignoreDiscriminator: boolean): TranscodeHWAccel { + return json as TranscodeHWAccel; +} + +export function TranscodeHWAccelToJSON(value?: TranscodeHWAccel | null): any { + return value as any; +} + diff --git a/open-api/typescript-sdk/fetch-client/models/TranscodePolicy.ts b/open-api/typescript-sdk/fetch-client/models/TranscodePolicy.ts new file mode 100644 index 0000000000..96afdbd608 --- /dev/null +++ b/open-api/typescript-sdk/fetch-client/models/TranscodePolicy.ts @@ -0,0 +1,41 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * Immich + * Immich API + * + * The version of the OpenAPI document: 1.94.1 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + + +/** + * + * @export + */ +export const TranscodePolicy = { + All: 'all', + Optimal: 'optimal', + Bitrate: 'bitrate', + Required: 'required', + Disabled: 'disabled' +} as const; +export type TranscodePolicy = typeof TranscodePolicy[keyof typeof TranscodePolicy]; + + +export function TranscodePolicyFromJSON(json: any): TranscodePolicy { + return TranscodePolicyFromJSONTyped(json, false); +} + +export function TranscodePolicyFromJSONTyped(json: any, ignoreDiscriminator: boolean): TranscodePolicy { + return json as TranscodePolicy; +} + +export function TranscodePolicyToJSON(value?: TranscodePolicy | null): any { + return value as any; +} + diff --git a/open-api/typescript-sdk/fetch-client/models/UpdateAlbumDto.ts b/open-api/typescript-sdk/fetch-client/models/UpdateAlbumDto.ts new file mode 100644 index 0000000000..d6fe84172b --- /dev/null +++ b/open-api/typescript-sdk/fetch-client/models/UpdateAlbumDto.ts @@ -0,0 +1,89 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * Immich + * Immich API + * + * The version of the OpenAPI document: 1.94.1 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + +import { exists, mapValues } from '../runtime'; +/** + * + * @export + * @interface UpdateAlbumDto + */ +export interface UpdateAlbumDto { + /** + * + * @type {string} + * @memberof UpdateAlbumDto + */ + albumName?: string; + /** + * + * @type {string} + * @memberof UpdateAlbumDto + */ + albumThumbnailAssetId?: string; + /** + * + * @type {string} + * @memberof UpdateAlbumDto + */ + description?: string; + /** + * + * @type {boolean} + * @memberof UpdateAlbumDto + */ + isActivityEnabled?: boolean; +} + +/** + * Check if a given object implements the UpdateAlbumDto interface. + */ +export function instanceOfUpdateAlbumDto(value: object): boolean { + let isInstance = true; + + return isInstance; +} + +export function UpdateAlbumDtoFromJSON(json: any): UpdateAlbumDto { + return UpdateAlbumDtoFromJSONTyped(json, false); +} + +export function UpdateAlbumDtoFromJSONTyped(json: any, ignoreDiscriminator: boolean): UpdateAlbumDto { + if ((json === undefined) || (json === null)) { + return json; + } + return { + + 'albumName': !exists(json, 'albumName') ? undefined : json['albumName'], + 'albumThumbnailAssetId': !exists(json, 'albumThumbnailAssetId') ? undefined : json['albumThumbnailAssetId'], + 'description': !exists(json, 'description') ? undefined : json['description'], + 'isActivityEnabled': !exists(json, 'isActivityEnabled') ? undefined : json['isActivityEnabled'], + }; +} + +export function UpdateAlbumDtoToJSON(value?: UpdateAlbumDto | null): any { + if (value === undefined) { + return undefined; + } + if (value === null) { + return null; + } + return { + + 'albumName': value.albumName, + 'albumThumbnailAssetId': value.albumThumbnailAssetId, + 'description': value.description, + 'isActivityEnabled': value.isActivityEnabled, + }; +} + diff --git a/open-api/typescript-sdk/fetch-client/models/UpdateAssetDto.ts b/open-api/typescript-sdk/fetch-client/models/UpdateAssetDto.ts new file mode 100644 index 0000000000..de19f0acca --- /dev/null +++ b/open-api/typescript-sdk/fetch-client/models/UpdateAssetDto.ts @@ -0,0 +1,105 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * Immich + * Immich API + * + * The version of the OpenAPI document: 1.94.1 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + +import { exists, mapValues } from '../runtime'; +/** + * + * @export + * @interface UpdateAssetDto + */ +export interface UpdateAssetDto { + /** + * + * @type {string} + * @memberof UpdateAssetDto + */ + dateTimeOriginal?: string; + /** + * + * @type {string} + * @memberof UpdateAssetDto + */ + description?: string; + /** + * + * @type {boolean} + * @memberof UpdateAssetDto + */ + isArchived?: boolean; + /** + * + * @type {boolean} + * @memberof UpdateAssetDto + */ + isFavorite?: boolean; + /** + * + * @type {number} + * @memberof UpdateAssetDto + */ + latitude?: number; + /** + * + * @type {number} + * @memberof UpdateAssetDto + */ + longitude?: number; +} + +/** + * Check if a given object implements the UpdateAssetDto interface. + */ +export function instanceOfUpdateAssetDto(value: object): boolean { + let isInstance = true; + + return isInstance; +} + +export function UpdateAssetDtoFromJSON(json: any): UpdateAssetDto { + return UpdateAssetDtoFromJSONTyped(json, false); +} + +export function UpdateAssetDtoFromJSONTyped(json: any, ignoreDiscriminator: boolean): UpdateAssetDto { + if ((json === undefined) || (json === null)) { + return json; + } + return { + + 'dateTimeOriginal': !exists(json, 'dateTimeOriginal') ? undefined : json['dateTimeOriginal'], + 'description': !exists(json, 'description') ? undefined : json['description'], + 'isArchived': !exists(json, 'isArchived') ? undefined : json['isArchived'], + 'isFavorite': !exists(json, 'isFavorite') ? undefined : json['isFavorite'], + 'latitude': !exists(json, 'latitude') ? undefined : json['latitude'], + 'longitude': !exists(json, 'longitude') ? undefined : json['longitude'], + }; +} + +export function UpdateAssetDtoToJSON(value?: UpdateAssetDto | null): any { + if (value === undefined) { + return undefined; + } + if (value === null) { + return null; + } + return { + + 'dateTimeOriginal': value.dateTimeOriginal, + 'description': value.description, + 'isArchived': value.isArchived, + 'isFavorite': value.isFavorite, + 'latitude': value.latitude, + 'longitude': value.longitude, + }; +} + diff --git a/open-api/typescript-sdk/fetch-client/models/UpdateLibraryDto.ts b/open-api/typescript-sdk/fetch-client/models/UpdateLibraryDto.ts new file mode 100644 index 0000000000..4a7c42f45d --- /dev/null +++ b/open-api/typescript-sdk/fetch-client/models/UpdateLibraryDto.ts @@ -0,0 +1,89 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * Immich + * Immich API + * + * The version of the OpenAPI document: 1.94.1 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + +import { exists, mapValues } from '../runtime'; +/** + * + * @export + * @interface UpdateLibraryDto + */ +export interface UpdateLibraryDto { + /** + * + * @type {Array} + * @memberof UpdateLibraryDto + */ + exclusionPatterns?: Array; + /** + * + * @type {Array} + * @memberof UpdateLibraryDto + */ + importPaths?: Array; + /** + * + * @type {boolean} + * @memberof UpdateLibraryDto + */ + isVisible?: boolean; + /** + * + * @type {string} + * @memberof UpdateLibraryDto + */ + name?: string; +} + +/** + * Check if a given object implements the UpdateLibraryDto interface. + */ +export function instanceOfUpdateLibraryDto(value: object): boolean { + let isInstance = true; + + return isInstance; +} + +export function UpdateLibraryDtoFromJSON(json: any): UpdateLibraryDto { + return UpdateLibraryDtoFromJSONTyped(json, false); +} + +export function UpdateLibraryDtoFromJSONTyped(json: any, ignoreDiscriminator: boolean): UpdateLibraryDto { + if ((json === undefined) || (json === null)) { + return json; + } + return { + + 'exclusionPatterns': !exists(json, 'exclusionPatterns') ? undefined : json['exclusionPatterns'], + 'importPaths': !exists(json, 'importPaths') ? undefined : json['importPaths'], + 'isVisible': !exists(json, 'isVisible') ? undefined : json['isVisible'], + 'name': !exists(json, 'name') ? undefined : json['name'], + }; +} + +export function UpdateLibraryDtoToJSON(value?: UpdateLibraryDto | null): any { + if (value === undefined) { + return undefined; + } + if (value === null) { + return null; + } + return { + + 'exclusionPatterns': value.exclusionPatterns, + 'importPaths': value.importPaths, + 'isVisible': value.isVisible, + 'name': value.name, + }; +} + diff --git a/open-api/typescript-sdk/fetch-client/models/UpdatePartnerDto.ts b/open-api/typescript-sdk/fetch-client/models/UpdatePartnerDto.ts new file mode 100644 index 0000000000..7f07462230 --- /dev/null +++ b/open-api/typescript-sdk/fetch-client/models/UpdatePartnerDto.ts @@ -0,0 +1,66 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * Immich + * Immich API + * + * The version of the OpenAPI document: 1.94.1 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + +import { exists, mapValues } from '../runtime'; +/** + * + * @export + * @interface UpdatePartnerDto + */ +export interface UpdatePartnerDto { + /** + * + * @type {boolean} + * @memberof UpdatePartnerDto + */ + inTimeline: boolean; +} + +/** + * Check if a given object implements the UpdatePartnerDto interface. + */ +export function instanceOfUpdatePartnerDto(value: object): boolean { + let isInstance = true; + isInstance = isInstance && "inTimeline" in value; + + return isInstance; +} + +export function UpdatePartnerDtoFromJSON(json: any): UpdatePartnerDto { + return UpdatePartnerDtoFromJSONTyped(json, false); +} + +export function UpdatePartnerDtoFromJSONTyped(json: any, ignoreDiscriminator: boolean): UpdatePartnerDto { + if ((json === undefined) || (json === null)) { + return json; + } + return { + + 'inTimeline': json['inTimeline'], + }; +} + +export function UpdatePartnerDtoToJSON(value?: UpdatePartnerDto | null): any { + if (value === undefined) { + return undefined; + } + if (value === null) { + return null; + } + return { + + 'inTimeline': value.inTimeline, + }; +} + diff --git a/open-api/typescript-sdk/fetch-client/models/UpdateStackParentDto.ts b/open-api/typescript-sdk/fetch-client/models/UpdateStackParentDto.ts new file mode 100644 index 0000000000..930d6f4ad6 --- /dev/null +++ b/open-api/typescript-sdk/fetch-client/models/UpdateStackParentDto.ts @@ -0,0 +1,75 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * Immich + * Immich API + * + * The version of the OpenAPI document: 1.94.1 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + +import { exists, mapValues } from '../runtime'; +/** + * + * @export + * @interface UpdateStackParentDto + */ +export interface UpdateStackParentDto { + /** + * + * @type {string} + * @memberof UpdateStackParentDto + */ + newParentId: string; + /** + * + * @type {string} + * @memberof UpdateStackParentDto + */ + oldParentId: string; +} + +/** + * Check if a given object implements the UpdateStackParentDto interface. + */ +export function instanceOfUpdateStackParentDto(value: object): boolean { + let isInstance = true; + isInstance = isInstance && "newParentId" in value; + isInstance = isInstance && "oldParentId" in value; + + return isInstance; +} + +export function UpdateStackParentDtoFromJSON(json: any): UpdateStackParentDto { + return UpdateStackParentDtoFromJSONTyped(json, false); +} + +export function UpdateStackParentDtoFromJSONTyped(json: any, ignoreDiscriminator: boolean): UpdateStackParentDto { + if ((json === undefined) || (json === null)) { + return json; + } + return { + + 'newParentId': json['newParentId'], + 'oldParentId': json['oldParentId'], + }; +} + +export function UpdateStackParentDtoToJSON(value?: UpdateStackParentDto | null): any { + if (value === undefined) { + return undefined; + } + if (value === null) { + return null; + } + return { + + 'newParentId': value.newParentId, + 'oldParentId': value.oldParentId, + }; +} + diff --git a/open-api/typescript-sdk/fetch-client/models/UpdateTagDto.ts b/open-api/typescript-sdk/fetch-client/models/UpdateTagDto.ts new file mode 100644 index 0000000000..dcc606048c --- /dev/null +++ b/open-api/typescript-sdk/fetch-client/models/UpdateTagDto.ts @@ -0,0 +1,65 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * Immich + * Immich API + * + * The version of the OpenAPI document: 1.94.1 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + +import { exists, mapValues } from '../runtime'; +/** + * + * @export + * @interface UpdateTagDto + */ +export interface UpdateTagDto { + /** + * + * @type {string} + * @memberof UpdateTagDto + */ + name?: string; +} + +/** + * Check if a given object implements the UpdateTagDto interface. + */ +export function instanceOfUpdateTagDto(value: object): boolean { + let isInstance = true; + + return isInstance; +} + +export function UpdateTagDtoFromJSON(json: any): UpdateTagDto { + return UpdateTagDtoFromJSONTyped(json, false); +} + +export function UpdateTagDtoFromJSONTyped(json: any, ignoreDiscriminator: boolean): UpdateTagDto { + if ((json === undefined) || (json === null)) { + return json; + } + return { + + 'name': !exists(json, 'name') ? undefined : json['name'], + }; +} + +export function UpdateTagDtoToJSON(value?: UpdateTagDto | null): any { + if (value === undefined) { + return undefined; + } + if (value === null) { + return null; + } + return { + + 'name': value.name, + }; +} + diff --git a/open-api/typescript-sdk/fetch-client/models/UpdateUserDto.ts b/open-api/typescript-sdk/fetch-client/models/UpdateUserDto.ts new file mode 100644 index 0000000000..8b6bc2fa97 --- /dev/null +++ b/open-api/typescript-sdk/fetch-client/models/UpdateUserDto.ts @@ -0,0 +1,153 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * Immich + * Immich API + * + * The version of the OpenAPI document: 1.94.1 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + +import { exists, mapValues } from '../runtime'; +import type { UserAvatarColor } from './UserAvatarColor'; +import { + UserAvatarColorFromJSON, + UserAvatarColorFromJSONTyped, + UserAvatarColorToJSON, +} from './UserAvatarColor'; + +/** + * + * @export + * @interface UpdateUserDto + */ +export interface UpdateUserDto { + /** + * + * @type {UserAvatarColor} + * @memberof UpdateUserDto + */ + avatarColor?: UserAvatarColor; + /** + * + * @type {string} + * @memberof UpdateUserDto + */ + email?: string; + /** + * + * @type {string} + * @memberof UpdateUserDto + */ + externalPath?: string; + /** + * + * @type {string} + * @memberof UpdateUserDto + */ + id: string; + /** + * + * @type {boolean} + * @memberof UpdateUserDto + */ + isAdmin?: boolean; + /** + * + * @type {boolean} + * @memberof UpdateUserDto + */ + memoriesEnabled?: boolean; + /** + * + * @type {string} + * @memberof UpdateUserDto + */ + name?: string; + /** + * + * @type {string} + * @memberof UpdateUserDto + */ + password?: string; + /** + * + * @type {number} + * @memberof UpdateUserDto + */ + quotaSizeInBytes?: number | null; + /** + * + * @type {boolean} + * @memberof UpdateUserDto + */ + shouldChangePassword?: boolean; + /** + * + * @type {string} + * @memberof UpdateUserDto + */ + storageLabel?: string; +} + +/** + * Check if a given object implements the UpdateUserDto interface. + */ +export function instanceOfUpdateUserDto(value: object): boolean { + let isInstance = true; + isInstance = isInstance && "id" in value; + + return isInstance; +} + +export function UpdateUserDtoFromJSON(json: any): UpdateUserDto { + return UpdateUserDtoFromJSONTyped(json, false); +} + +export function UpdateUserDtoFromJSONTyped(json: any, ignoreDiscriminator: boolean): UpdateUserDto { + if ((json === undefined) || (json === null)) { + return json; + } + return { + + 'avatarColor': !exists(json, 'avatarColor') ? undefined : UserAvatarColorFromJSON(json['avatarColor']), + 'email': !exists(json, 'email') ? undefined : json['email'], + 'externalPath': !exists(json, 'externalPath') ? undefined : json['externalPath'], + 'id': json['id'], + 'isAdmin': !exists(json, 'isAdmin') ? undefined : json['isAdmin'], + 'memoriesEnabled': !exists(json, 'memoriesEnabled') ? undefined : json['memoriesEnabled'], + 'name': !exists(json, 'name') ? undefined : json['name'], + 'password': !exists(json, 'password') ? undefined : json['password'], + 'quotaSizeInBytes': !exists(json, 'quotaSizeInBytes') ? undefined : json['quotaSizeInBytes'], + 'shouldChangePassword': !exists(json, 'shouldChangePassword') ? undefined : json['shouldChangePassword'], + 'storageLabel': !exists(json, 'storageLabel') ? undefined : json['storageLabel'], + }; +} + +export function UpdateUserDtoToJSON(value?: UpdateUserDto | null): any { + if (value === undefined) { + return undefined; + } + if (value === null) { + return null; + } + return { + + 'avatarColor': UserAvatarColorToJSON(value.avatarColor), + 'email': value.email, + 'externalPath': value.externalPath, + 'id': value.id, + 'isAdmin': value.isAdmin, + 'memoriesEnabled': value.memoriesEnabled, + 'name': value.name, + 'password': value.password, + 'quotaSizeInBytes': value.quotaSizeInBytes, + 'shouldChangePassword': value.shouldChangePassword, + 'storageLabel': value.storageLabel, + }; +} + diff --git a/open-api/typescript-sdk/fetch-client/models/UsageByUserDto.ts b/open-api/typescript-sdk/fetch-client/models/UsageByUserDto.ts new file mode 100644 index 0000000000..bb66d92654 --- /dev/null +++ b/open-api/typescript-sdk/fetch-client/models/UsageByUserDto.ts @@ -0,0 +1,111 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * Immich + * Immich API + * + * The version of the OpenAPI document: 1.94.1 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + +import { exists, mapValues } from '../runtime'; +/** + * + * @export + * @interface UsageByUserDto + */ +export interface UsageByUserDto { + /** + * + * @type {number} + * @memberof UsageByUserDto + */ + photos: number; + /** + * + * @type {number} + * @memberof UsageByUserDto + */ + quotaSizeInBytes: number | null; + /** + * + * @type {number} + * @memberof UsageByUserDto + */ + usage: number; + /** + * + * @type {string} + * @memberof UsageByUserDto + */ + userId: string; + /** + * + * @type {string} + * @memberof UsageByUserDto + */ + userName: string; + /** + * + * @type {number} + * @memberof UsageByUserDto + */ + videos: number; +} + +/** + * Check if a given object implements the UsageByUserDto interface. + */ +export function instanceOfUsageByUserDto(value: object): boolean { + let isInstance = true; + isInstance = isInstance && "photos" in value; + isInstance = isInstance && "quotaSizeInBytes" in value; + isInstance = isInstance && "usage" in value; + isInstance = isInstance && "userId" in value; + isInstance = isInstance && "userName" in value; + isInstance = isInstance && "videos" in value; + + return isInstance; +} + +export function UsageByUserDtoFromJSON(json: any): UsageByUserDto { + return UsageByUserDtoFromJSONTyped(json, false); +} + +export function UsageByUserDtoFromJSONTyped(json: any, ignoreDiscriminator: boolean): UsageByUserDto { + if ((json === undefined) || (json === null)) { + return json; + } + return { + + 'photos': json['photos'], + 'quotaSizeInBytes': json['quotaSizeInBytes'], + 'usage': json['usage'], + 'userId': json['userId'], + 'userName': json['userName'], + 'videos': json['videos'], + }; +} + +export function UsageByUserDtoToJSON(value?: UsageByUserDto | null): any { + if (value === undefined) { + return undefined; + } + if (value === null) { + return null; + } + return { + + 'photos': value.photos, + 'quotaSizeInBytes': value.quotaSizeInBytes, + 'usage': value.usage, + 'userId': value.userId, + 'userName': value.userName, + 'videos': value.videos, + }; +} + diff --git a/open-api/typescript-sdk/fetch-client/models/UserAvatarColor.ts b/open-api/typescript-sdk/fetch-client/models/UserAvatarColor.ts new file mode 100644 index 0000000000..cf7632a3f3 --- /dev/null +++ b/open-api/typescript-sdk/fetch-client/models/UserAvatarColor.ts @@ -0,0 +1,46 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * Immich + * Immich API + * + * The version of the OpenAPI document: 1.94.1 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + + +/** + * + * @export + */ +export const UserAvatarColor = { + Primary: 'primary', + Pink: 'pink', + Red: 'red', + Yellow: 'yellow', + Blue: 'blue', + Green: 'green', + Purple: 'purple', + Orange: 'orange', + Gray: 'gray', + Amber: 'amber' +} as const; +export type UserAvatarColor = typeof UserAvatarColor[keyof typeof UserAvatarColor]; + + +export function UserAvatarColorFromJSON(json: any): UserAvatarColor { + return UserAvatarColorFromJSONTyped(json, false); +} + +export function UserAvatarColorFromJSONTyped(json: any, ignoreDiscriminator: boolean): UserAvatarColor { + return json as UserAvatarColor; +} + +export function UserAvatarColorToJSON(value?: UserAvatarColor | null): any { + return value as any; +} + diff --git a/open-api/typescript-sdk/fetch-client/models/UserDto.ts b/open-api/typescript-sdk/fetch-client/models/UserDto.ts new file mode 100644 index 0000000000..40d35810a8 --- /dev/null +++ b/open-api/typescript-sdk/fetch-client/models/UserDto.ts @@ -0,0 +1,109 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * Immich + * Immich API + * + * The version of the OpenAPI document: 1.94.1 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + +import { exists, mapValues } from '../runtime'; +import type { UserAvatarColor } from './UserAvatarColor'; +import { + UserAvatarColorFromJSON, + UserAvatarColorFromJSONTyped, + UserAvatarColorToJSON, +} from './UserAvatarColor'; + +/** + * + * @export + * @interface UserDto + */ +export interface UserDto { + /** + * + * @type {UserAvatarColor} + * @memberof UserDto + */ + avatarColor: UserAvatarColor; + /** + * + * @type {string} + * @memberof UserDto + */ + email: string; + /** + * + * @type {string} + * @memberof UserDto + */ + id: string; + /** + * + * @type {string} + * @memberof UserDto + */ + name: string; + /** + * + * @type {string} + * @memberof UserDto + */ + profileImagePath: string; +} + +/** + * Check if a given object implements the UserDto interface. + */ +export function instanceOfUserDto(value: object): boolean { + let isInstance = true; + isInstance = isInstance && "avatarColor" in value; + isInstance = isInstance && "email" in value; + isInstance = isInstance && "id" in value; + isInstance = isInstance && "name" in value; + isInstance = isInstance && "profileImagePath" in value; + + return isInstance; +} + +export function UserDtoFromJSON(json: any): UserDto { + return UserDtoFromJSONTyped(json, false); +} + +export function UserDtoFromJSONTyped(json: any, ignoreDiscriminator: boolean): UserDto { + if ((json === undefined) || (json === null)) { + return json; + } + return { + + 'avatarColor': UserAvatarColorFromJSON(json['avatarColor']), + 'email': json['email'], + 'id': json['id'], + 'name': json['name'], + 'profileImagePath': json['profileImagePath'], + }; +} + +export function UserDtoToJSON(value?: UserDto | null): any { + if (value === undefined) { + return undefined; + } + if (value === null) { + return null; + } + return { + + 'avatarColor': UserAvatarColorToJSON(value.avatarColor), + 'email': value.email, + 'id': value.id, + 'name': value.name, + 'profileImagePath': value.profileImagePath, + }; +} + diff --git a/open-api/typescript-sdk/fetch-client/models/UserResponseDto.ts b/open-api/typescript-sdk/fetch-client/models/UserResponseDto.ts new file mode 100644 index 0000000000..b606a3052c --- /dev/null +++ b/open-api/typescript-sdk/fetch-client/models/UserResponseDto.ts @@ -0,0 +1,207 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * Immich + * Immich API + * + * The version of the OpenAPI document: 1.94.1 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + +import { exists, mapValues } from '../runtime'; +import type { UserAvatarColor } from './UserAvatarColor'; +import { + UserAvatarColorFromJSON, + UserAvatarColorFromJSONTyped, + UserAvatarColorToJSON, +} from './UserAvatarColor'; + +/** + * + * @export + * @interface UserResponseDto + */ +export interface UserResponseDto { + /** + * + * @type {UserAvatarColor} + * @memberof UserResponseDto + */ + avatarColor: UserAvatarColor; + /** + * + * @type {Date} + * @memberof UserResponseDto + */ + createdAt: Date; + /** + * + * @type {Date} + * @memberof UserResponseDto + */ + deletedAt: Date | null; + /** + * + * @type {string} + * @memberof UserResponseDto + */ + email: string; + /** + * + * @type {string} + * @memberof UserResponseDto + */ + externalPath: string | null; + /** + * + * @type {string} + * @memberof UserResponseDto + */ + id: string; + /** + * + * @type {boolean} + * @memberof UserResponseDto + */ + isAdmin: boolean; + /** + * + * @type {boolean} + * @memberof UserResponseDto + */ + memoriesEnabled?: boolean; + /** + * + * @type {string} + * @memberof UserResponseDto + */ + name: string; + /** + * + * @type {string} + * @memberof UserResponseDto + */ + oauthId: string; + /** + * + * @type {string} + * @memberof UserResponseDto + */ + profileImagePath: string; + /** + * + * @type {number} + * @memberof UserResponseDto + */ + quotaSizeInBytes: number | null; + /** + * + * @type {number} + * @memberof UserResponseDto + */ + quotaUsageInBytes: number | null; + /** + * + * @type {boolean} + * @memberof UserResponseDto + */ + shouldChangePassword: boolean; + /** + * + * @type {string} + * @memberof UserResponseDto + */ + storageLabel: string | null; + /** + * + * @type {Date} + * @memberof UserResponseDto + */ + updatedAt: Date; +} + +/** + * Check if a given object implements the UserResponseDto interface. + */ +export function instanceOfUserResponseDto(value: object): boolean { + let isInstance = true; + isInstance = isInstance && "avatarColor" in value; + isInstance = isInstance && "createdAt" in value; + isInstance = isInstance && "deletedAt" in value; + isInstance = isInstance && "email" in value; + isInstance = isInstance && "externalPath" in value; + isInstance = isInstance && "id" in value; + isInstance = isInstance && "isAdmin" in value; + isInstance = isInstance && "name" in value; + isInstance = isInstance && "oauthId" in value; + isInstance = isInstance && "profileImagePath" in value; + isInstance = isInstance && "quotaSizeInBytes" in value; + isInstance = isInstance && "quotaUsageInBytes" in value; + isInstance = isInstance && "shouldChangePassword" in value; + isInstance = isInstance && "storageLabel" in value; + isInstance = isInstance && "updatedAt" in value; + + return isInstance; +} + +export function UserResponseDtoFromJSON(json: any): UserResponseDto { + return UserResponseDtoFromJSONTyped(json, false); +} + +export function UserResponseDtoFromJSONTyped(json: any, ignoreDiscriminator: boolean): UserResponseDto { + if ((json === undefined) || (json === null)) { + return json; + } + return { + + 'avatarColor': UserAvatarColorFromJSON(json['avatarColor']), + 'createdAt': (new Date(json['createdAt'])), + 'deletedAt': (json['deletedAt'] === null ? null : new Date(json['deletedAt'])), + 'email': json['email'], + 'externalPath': json['externalPath'], + 'id': json['id'], + 'isAdmin': json['isAdmin'], + 'memoriesEnabled': !exists(json, 'memoriesEnabled') ? undefined : json['memoriesEnabled'], + 'name': json['name'], + 'oauthId': json['oauthId'], + 'profileImagePath': json['profileImagePath'], + 'quotaSizeInBytes': json['quotaSizeInBytes'], + 'quotaUsageInBytes': json['quotaUsageInBytes'], + 'shouldChangePassword': json['shouldChangePassword'], + 'storageLabel': json['storageLabel'], + 'updatedAt': (new Date(json['updatedAt'])), + }; +} + +export function UserResponseDtoToJSON(value?: UserResponseDto | null): any { + if (value === undefined) { + return undefined; + } + if (value === null) { + return null; + } + return { + + 'avatarColor': UserAvatarColorToJSON(value.avatarColor), + 'createdAt': (value.createdAt.toISOString()), + 'deletedAt': (value.deletedAt === null ? null : value.deletedAt.toISOString()), + 'email': value.email, + 'externalPath': value.externalPath, + 'id': value.id, + 'isAdmin': value.isAdmin, + 'memoriesEnabled': value.memoriesEnabled, + 'name': value.name, + 'oauthId': value.oauthId, + 'profileImagePath': value.profileImagePath, + 'quotaSizeInBytes': value.quotaSizeInBytes, + 'quotaUsageInBytes': value.quotaUsageInBytes, + 'shouldChangePassword': value.shouldChangePassword, + 'storageLabel': value.storageLabel, + 'updatedAt': (value.updatedAt.toISOString()), + }; +} + diff --git a/open-api/typescript-sdk/fetch-client/models/ValidateAccessTokenResponseDto.ts b/open-api/typescript-sdk/fetch-client/models/ValidateAccessTokenResponseDto.ts new file mode 100644 index 0000000000..028be01f2c --- /dev/null +++ b/open-api/typescript-sdk/fetch-client/models/ValidateAccessTokenResponseDto.ts @@ -0,0 +1,66 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * Immich + * Immich API + * + * The version of the OpenAPI document: 1.94.1 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + +import { exists, mapValues } from '../runtime'; +/** + * + * @export + * @interface ValidateAccessTokenResponseDto + */ +export interface ValidateAccessTokenResponseDto { + /** + * + * @type {boolean} + * @memberof ValidateAccessTokenResponseDto + */ + authStatus: boolean; +} + +/** + * Check if a given object implements the ValidateAccessTokenResponseDto interface. + */ +export function instanceOfValidateAccessTokenResponseDto(value: object): boolean { + let isInstance = true; + isInstance = isInstance && "authStatus" in value; + + return isInstance; +} + +export function ValidateAccessTokenResponseDtoFromJSON(json: any): ValidateAccessTokenResponseDto { + return ValidateAccessTokenResponseDtoFromJSONTyped(json, false); +} + +export function ValidateAccessTokenResponseDtoFromJSONTyped(json: any, ignoreDiscriminator: boolean): ValidateAccessTokenResponseDto { + if ((json === undefined) || (json === null)) { + return json; + } + return { + + 'authStatus': json['authStatus'], + }; +} + +export function ValidateAccessTokenResponseDtoToJSON(value?: ValidateAccessTokenResponseDto | null): any { + if (value === undefined) { + return undefined; + } + if (value === null) { + return null; + } + return { + + 'authStatus': value.authStatus, + }; +} + diff --git a/open-api/typescript-sdk/fetch-client/models/VideoCodec.ts b/open-api/typescript-sdk/fetch-client/models/VideoCodec.ts new file mode 100644 index 0000000000..820491caa0 --- /dev/null +++ b/open-api/typescript-sdk/fetch-client/models/VideoCodec.ts @@ -0,0 +1,39 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * Immich + * Immich API + * + * The version of the OpenAPI document: 1.94.1 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + + +/** + * + * @export + */ +export const VideoCodec = { + H264: 'h264', + Hevc: 'hevc', + Vp9: 'vp9' +} as const; +export type VideoCodec = typeof VideoCodec[keyof typeof VideoCodec]; + + +export function VideoCodecFromJSON(json: any): VideoCodec { + return VideoCodecFromJSONTyped(json, false); +} + +export function VideoCodecFromJSONTyped(json: any, ignoreDiscriminator: boolean): VideoCodec { + return json as VideoCodec; +} + +export function VideoCodecToJSON(value?: VideoCodec | null): any { + return value as any; +} + diff --git a/open-api/typescript-sdk/fetch-client/models/index.ts b/open-api/typescript-sdk/fetch-client/models/index.ts new file mode 100644 index 0000000000..ce30d3afe8 --- /dev/null +++ b/open-api/typescript-sdk/fetch-client/models/index.ts @@ -0,0 +1,160 @@ +/* tslint:disable */ +/* eslint-disable */ +export * from './APIKeyCreateDto'; +export * from './APIKeyCreateResponseDto'; +export * from './APIKeyResponseDto'; +export * from './APIKeyUpdateDto'; +export * from './ActivityCreateDto'; +export * from './ActivityResponseDto'; +export * from './ActivityStatisticsResponseDto'; +export * from './AddUsersDto'; +export * from './AlbumCountResponseDto'; +export * from './AlbumResponseDto'; +export * from './AllJobStatusResponseDto'; +export * from './AssetBulkDeleteDto'; +export * from './AssetBulkUpdateDto'; +export * from './AssetBulkUploadCheckDto'; +export * from './AssetBulkUploadCheckItem'; +export * from './AssetBulkUploadCheckResponseDto'; +export * from './AssetBulkUploadCheckResult'; +export * from './AssetFaceResponseDto'; +export * from './AssetFaceUpdateDto'; +export * from './AssetFaceUpdateItem'; +export * from './AssetFaceWithoutPersonResponseDto'; +export * from './AssetFileUploadResponseDto'; +export * from './AssetIdsDto'; +export * from './AssetIdsResponseDto'; +export * from './AssetJobName'; +export * from './AssetJobsDto'; +export * from './AssetOrder'; +export * from './AssetResponseDto'; +export * from './AssetStatsResponseDto'; +export * from './AssetTypeEnum'; +export * from './AudioCodec'; +export * from './AuditDeletesResponseDto'; +export * from './AuthDeviceResponseDto'; +export * from './BulkIdResponseDto'; +export * from './BulkIdsDto'; +export * from './CLIPConfig'; +export * from './CLIPMode'; +export * from './CQMode'; +export * from './ChangePasswordDto'; +export * from './CheckExistingAssetsDto'; +export * from './CheckExistingAssetsResponseDto'; +export * from './Colorspace'; +export * from './CreateAlbumDto'; +export * from './CreateLibraryDto'; +export * from './CreateProfileImageResponseDto'; +export * from './CreateTagDto'; +export * from './CreateUserDto'; +export * from './CuratedLocationsResponseDto'; +export * from './CuratedObjectsResponseDto'; +export * from './DownloadArchiveInfo'; +export * from './DownloadInfoDto'; +export * from './DownloadResponseDto'; +export * from './EntityType'; +export * from './ExifResponseDto'; +export * from './FaceDto'; +export * from './FileChecksumDto'; +export * from './FileChecksumResponseDto'; +export * from './FileReportDto'; +export * from './FileReportFixDto'; +export * from './FileReportItemDto'; +export * from './JobCommand'; +export * from './JobCommandDto'; +export * from './JobCountsDto'; +export * from './JobName'; +export * from './JobSettingsDto'; +export * from './JobStatusDto'; +export * from './LibraryResponseDto'; +export * from './LibraryStatsResponseDto'; +export * from './LibraryType'; +export * from './LogLevel'; +export * from './LoginCredentialDto'; +export * from './LoginResponseDto'; +export * from './LogoutResponseDto'; +export * from './MapMarkerResponseDto'; +export * from './MapTheme'; +export * from './MemoryLaneResponseDto'; +export * from './MergePersonDto'; +export * from './ModelType'; +export * from './OAuthAuthorizeResponseDto'; +export * from './OAuthCallbackDto'; +export * from './OAuthConfigDto'; +export * from './OAuthConfigResponseDto'; +export * from './PartnerResponseDto'; +export * from './PathEntityType'; +export * from './PathType'; +export * from './PeopleResponseDto'; +export * from './PeopleUpdateDto'; +export * from './PeopleUpdateItem'; +export * from './PersonResponseDto'; +export * from './PersonStatisticsResponseDto'; +export * from './PersonUpdateDto'; +export * from './PersonWithFacesResponseDto'; +export * from './QueueStatusDto'; +export * from './ReactionLevel'; +export * from './ReactionType'; +export * from './RecognitionConfig'; +export * from './ScanLibraryDto'; +export * from './SearchAlbumResponseDto'; +export * from './SearchAssetResponseDto'; +export * from './SearchExploreItem'; +export * from './SearchExploreResponseDto'; +export * from './SearchFacetCountResponseDto'; +export * from './SearchFacetResponseDto'; +export * from './SearchResponseDto'; +export * from './ServerConfigDto'; +export * from './ServerFeaturesDto'; +export * from './ServerInfoResponseDto'; +export * from './ServerMediaTypesResponseDto'; +export * from './ServerPingResponse'; +export * from './ServerStatsResponseDto'; +export * from './ServerThemeDto'; +export * from './ServerVersionResponseDto'; +export * from './SharedLinkCreateDto'; +export * from './SharedLinkEditDto'; +export * from './SharedLinkResponseDto'; +export * from './SharedLinkType'; +export * from './SignUpDto'; +export * from './SmartInfoResponseDto'; +export * from './SystemConfigDto'; +export * from './SystemConfigFFmpegDto'; +export * from './SystemConfigJobDto'; +export * from './SystemConfigLibraryDto'; +export * from './SystemConfigLibraryScanDto'; +export * from './SystemConfigLibraryWatchDto'; +export * from './SystemConfigLoggingDto'; +export * from './SystemConfigMachineLearningDto'; +export * from './SystemConfigMapDto'; +export * from './SystemConfigNewVersionCheckDto'; +export * from './SystemConfigOAuthDto'; +export * from './SystemConfigPasswordLoginDto'; +export * from './SystemConfigReverseGeocodingDto'; +export * from './SystemConfigServerDto'; +export * from './SystemConfigStorageTemplateDto'; +export * from './SystemConfigTemplateStorageOptionDto'; +export * from './SystemConfigThemeDto'; +export * from './SystemConfigThumbnailDto'; +export * from './SystemConfigTrashDto'; +export * from './TagResponseDto'; +export * from './TagTypeEnum'; +export * from './ThumbnailFormat'; +export * from './TimeBucketResponseDto'; +export * from './TimeBucketSize'; +export * from './ToneMapping'; +export * from './TranscodeHWAccel'; +export * from './TranscodePolicy'; +export * from './UpdateAlbumDto'; +export * from './UpdateAssetDto'; +export * from './UpdateLibraryDto'; +export * from './UpdatePartnerDto'; +export * from './UpdateStackParentDto'; +export * from './UpdateTagDto'; +export * from './UpdateUserDto'; +export * from './UsageByUserDto'; +export * from './UserAvatarColor'; +export * from './UserDto'; +export * from './UserResponseDto'; +export * from './ValidateAccessTokenResponseDto'; +export * from './VideoCodec'; diff --git a/open-api/typescript-sdk/fetch-client/runtime.ts b/open-api/typescript-sdk/fetch-client/runtime.ts new file mode 100644 index 0000000000..0661620add --- /dev/null +++ b/open-api/typescript-sdk/fetch-client/runtime.ts @@ -0,0 +1,431 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * Immich + * Immich API + * + * The version of the OpenAPI document: 1.94.1 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + + +export const BASE_PATH = "/api".replace(/\/+$/, ""); + +export interface ConfigurationParameters { + basePath?: string; // override base path + fetchApi?: FetchAPI; // override for fetch implementation + middleware?: Middleware[]; // middleware to apply before/after fetch requests + queryParamsStringify?: (params: HTTPQuery) => string; // stringify function for query strings + username?: string; // parameter for basic security + password?: string; // parameter for basic security + apiKey?: string | ((name: string) => string); // parameter for apiKey security + accessToken?: string | Promise | ((name?: string, scopes?: string[]) => string | Promise); // parameter for oauth2 security + headers?: HTTPHeaders; //header params we want to use on every request + credentials?: RequestCredentials; //value for the credentials param we want to use on each request +} + +export class Configuration { + constructor(private configuration: ConfigurationParameters = {}) {} + + set config(configuration: Configuration) { + this.configuration = configuration; + } + + get basePath(): string { + return this.configuration.basePath != null ? this.configuration.basePath : BASE_PATH; + } + + get fetchApi(): FetchAPI | undefined { + return this.configuration.fetchApi; + } + + get middleware(): Middleware[] { + return this.configuration.middleware || []; + } + + get queryParamsStringify(): (params: HTTPQuery) => string { + return this.configuration.queryParamsStringify || querystring; + } + + get username(): string | undefined { + return this.configuration.username; + } + + get password(): string | undefined { + return this.configuration.password; + } + + get apiKey(): ((name: string) => string) | undefined { + const apiKey = this.configuration.apiKey; + if (apiKey) { + return typeof apiKey === 'function' ? apiKey : () => apiKey; + } + return undefined; + } + + get accessToken(): ((name?: string, scopes?: string[]) => string | Promise) | undefined { + const accessToken = this.configuration.accessToken; + if (accessToken) { + return typeof accessToken === 'function' ? accessToken : async () => accessToken; + } + return undefined; + } + + get headers(): HTTPHeaders | undefined { + return this.configuration.headers; + } + + get credentials(): RequestCredentials | undefined { + return this.configuration.credentials; + } +} + +export const DefaultConfig = new Configuration(); + +/** + * This is the base class for all generated API classes. + */ +export class BaseAPI { + + private static readonly jsonRegex = new RegExp('^(:?application\/json|[^;/ \t]+\/[^;/ \t]+[+]json)[ \t]*(:?;.*)?$', 'i'); + private middleware: Middleware[]; + + constructor(protected configuration = DefaultConfig) { + this.middleware = configuration.middleware; + } + + withMiddleware(this: T, ...middlewares: Middleware[]) { + const next = this.clone(); + next.middleware = next.middleware.concat(...middlewares); + return next; + } + + withPreMiddleware(this: T, ...preMiddlewares: Array) { + const middlewares = preMiddlewares.map((pre) => ({ pre })); + return this.withMiddleware(...middlewares); + } + + withPostMiddleware(this: T, ...postMiddlewares: Array) { + const middlewares = postMiddlewares.map((post) => ({ post })); + return this.withMiddleware(...middlewares); + } + + /** + * Check if the given MIME is a JSON MIME. + * JSON MIME examples: + * application/json + * application/json; charset=UTF8 + * APPLICATION/JSON + * application/vnd.company+json + * @param mime - MIME (Multipurpose Internet Mail Extensions) + * @return True if the given MIME is JSON, false otherwise. + */ + protected isJsonMime(mime: string | null | undefined): boolean { + if (!mime) { + return false; + } + return BaseAPI.jsonRegex.test(mime); + } + + protected async request(context: RequestOpts, initOverrides?: RequestInit | InitOverrideFunction): Promise { + const { url, init } = await this.createFetchParams(context, initOverrides); + const response = await this.fetchApi(url, init); + if (response && (response.status >= 200 && response.status < 300)) { + return response; + } + throw new ResponseError(response, 'Response returned an error code'); + } + + private async createFetchParams(context: RequestOpts, initOverrides?: RequestInit | InitOverrideFunction) { + let url = this.configuration.basePath + context.path; + if (context.query !== undefined && Object.keys(context.query).length !== 0) { + // only add the querystring to the URL if there are query parameters. + // this is done to avoid urls ending with a "?" character which buggy webservers + // do not handle correctly sometimes. + url += '?' + this.configuration.queryParamsStringify(context.query); + } + + const headers = Object.assign({}, this.configuration.headers, context.headers); + Object.keys(headers).forEach(key => headers[key] === undefined ? delete headers[key] : {}); + + const initOverrideFn = + typeof initOverrides === "function" + ? initOverrides + : async () => initOverrides; + + const initParams = { + method: context.method, + headers, + body: context.body, + credentials: this.configuration.credentials, + }; + + const overriddenInit: RequestInit = { + ...initParams, + ...(await initOverrideFn({ + init: initParams, + context, + })) + }; + + let body: any; + if (isFormData(overriddenInit.body) + || (overriddenInit.body instanceof URLSearchParams) + || isBlob(overriddenInit.body)) { + body = overriddenInit.body; + } else if (this.isJsonMime(headers['Content-Type'])) { + body = JSON.stringify(overriddenInit.body); + } else { + body = overriddenInit.body; + } + + const init: RequestInit = { + ...overriddenInit, + body + }; + + return { url, init }; + } + + private fetchApi = async (url: string, init: RequestInit) => { + let fetchParams = { url, init }; + for (const middleware of this.middleware) { + if (middleware.pre) { + fetchParams = await middleware.pre({ + fetch: this.fetchApi, + ...fetchParams, + }) || fetchParams; + } + } + let response: Response | undefined = undefined; + try { + response = await (this.configuration.fetchApi || fetch)(fetchParams.url, fetchParams.init); + } catch (e) { + for (const middleware of this.middleware) { + if (middleware.onError) { + response = await middleware.onError({ + fetch: this.fetchApi, + url: fetchParams.url, + init: fetchParams.init, + error: e, + response: response ? response.clone() : undefined, + }) || response; + } + } + if (response === undefined) { + if (e instanceof Error) { + throw new FetchError(e, 'The request failed and the interceptors did not return an alternative response'); + } else { + throw e; + } + } + } + for (const middleware of this.middleware) { + if (middleware.post) { + response = await middleware.post({ + fetch: this.fetchApi, + url: fetchParams.url, + init: fetchParams.init, + response: response.clone(), + }) || response; + } + } + return response; + } + + /** + * Create a shallow clone of `this` by constructing a new instance + * and then shallow cloning data members. + */ + private clone(this: T): T { + const constructor = this.constructor as any; + const next = new constructor(this.configuration); + next.middleware = this.middleware.slice(); + return next; + } +}; + +function isBlob(value: any): value is Blob { + return typeof Blob !== 'undefined' && value instanceof Blob; +} + +function isFormData(value: any): value is FormData { + return typeof FormData !== "undefined" && value instanceof FormData; +} + +export class ResponseError extends Error { + override name: "ResponseError" = "ResponseError"; + constructor(public response: Response, msg?: string) { + super(msg); + } +} + +export class FetchError extends Error { + override name: "FetchError" = "FetchError"; + constructor(public cause: Error, msg?: string) { + super(msg); + } +} + +export class RequiredError extends Error { + override name: "RequiredError" = "RequiredError"; + constructor(public field: string, msg?: string) { + super(msg); + } +} + +export const COLLECTION_FORMATS = { + csv: ",", + ssv: " ", + tsv: "\t", + pipes: "|", +}; + +export type FetchAPI = WindowOrWorkerGlobalScope['fetch']; + +export type Json = any; +export type HTTPMethod = 'GET' | 'POST' | 'PUT' | 'PATCH' | 'DELETE' | 'OPTIONS' | 'HEAD'; +export type HTTPHeaders = { [key: string]: string }; +export type HTTPQuery = { [key: string]: string | number | null | boolean | Array | Set | HTTPQuery }; +export type HTTPBody = Json | FormData | URLSearchParams; +export type HTTPRequestInit = { headers?: HTTPHeaders; method: HTTPMethod; credentials?: RequestCredentials; body?: HTTPBody }; +export type ModelPropertyNaming = 'camelCase' | 'snake_case' | 'PascalCase' | 'original'; + +export type InitOverrideFunction = (requestContext: { init: HTTPRequestInit, context: RequestOpts }) => Promise + +export interface FetchParams { + url: string; + init: RequestInit; +} + +export interface RequestOpts { + path: string; + method: HTTPMethod; + headers: HTTPHeaders; + query?: HTTPQuery; + body?: HTTPBody; +} + +export function exists(json: any, key: string) { + const value = json[key]; + return value !== null && value !== undefined; +} + +export function querystring(params: HTTPQuery, prefix: string = ''): string { + return Object.keys(params) + .map(key => querystringSingleKey(key, params[key], prefix)) + .filter(part => part.length > 0) + .join('&'); +} + +function querystringSingleKey(key: string, value: string | number | null | undefined | boolean | Array | Set | HTTPQuery, keyPrefix: string = ''): string { + const fullKey = keyPrefix + (keyPrefix.length ? `[${key}]` : key); + if (value instanceof Array) { + const multiValue = value.map(singleValue => encodeURIComponent(String(singleValue))) + .join(`&${encodeURIComponent(fullKey)}=`); + return `${encodeURIComponent(fullKey)}=${multiValue}`; + } + if (value instanceof Set) { + const valueAsArray = Array.from(value); + return querystringSingleKey(key, valueAsArray, keyPrefix); + } + if (value instanceof Date) { + return `${encodeURIComponent(fullKey)}=${encodeURIComponent(value.toISOString())}`; + } + if (value instanceof Object) { + return querystring(value as HTTPQuery, fullKey); + } + return `${encodeURIComponent(fullKey)}=${encodeURIComponent(String(value))}`; +} + +export function mapValues(data: any, fn: (item: any) => any) { + return Object.keys(data).reduce( + (acc, key) => ({ ...acc, [key]: fn(data[key]) }), + {} + ); +} + +export function canConsumeForm(consumes: Consume[]): boolean { + for (const consume of consumes) { + if ('multipart/form-data' === consume.contentType) { + return true; + } + } + return false; +} + +export interface Consume { + contentType: string; +} + +export interface RequestContext { + fetch: FetchAPI; + url: string; + init: RequestInit; +} + +export interface ResponseContext { + fetch: FetchAPI; + url: string; + init: RequestInit; + response: Response; +} + +export interface ErrorContext { + fetch: FetchAPI; + url: string; + init: RequestInit; + error: unknown; + response?: Response; +} + +export interface Middleware { + pre?(context: RequestContext): Promise; + post?(context: ResponseContext): Promise; + onError?(context: ErrorContext): Promise; +} + +export interface ApiResponse { + raw: Response; + value(): Promise; +} + +export interface ResponseTransformer { + (json: any): T; +} + +export class JSONApiResponse { + constructor(public raw: Response, private transformer: ResponseTransformer = (jsonValue: any) => jsonValue) {} + + async value(): Promise { + return this.transformer(await this.raw.json()); + } +} + +export class VoidApiResponse { + constructor(public raw: Response) {} + + async value(): Promise { + return undefined; + } +} + +export class BlobApiResponse { + constructor(public raw: Response) {} + + async value(): Promise { + return await this.raw.blob(); + }; +} + +export class TextApiResponse { + constructor(public raw: Response) {} + + async value(): Promise { + return await this.raw.text(); + }; +} diff --git a/open-api/typescript-sdk/fetch.ts b/open-api/typescript-sdk/fetch.ts new file mode 100644 index 0000000000..5441cd8268 --- /dev/null +++ b/open-api/typescript-sdk/fetch.ts @@ -0,0 +1 @@ +export * from './fetch-client'; diff --git a/open-api/typescript-sdk/index.ts b/open-api/typescript-sdk/index.ts deleted file mode 100644 index eb7f6b43e0..0000000000 --- a/open-api/typescript-sdk/index.ts +++ /dev/null @@ -1,4 +0,0 @@ -export * from './client'; -export * as base from './client/base'; -export * as configuration from './client/configuration'; -export * as common from './client/common'; diff --git a/open-api/typescript-sdk/package.json b/open-api/typescript-sdk/package.json index e1c94e5b66..5175fcf4a1 100644 --- a/open-api/typescript-sdk/package.json +++ b/open-api/typescript-sdk/package.json @@ -3,23 +3,32 @@ "version": "1.92.1", "description": "", "type": "module", - "main": "./build/index.js", - "types": "./build/index.d.ts", + "main": "./build/fetch/index.js", + "types": "./build/fetch/index.d.ts", "exports": { + "./axios": { + "types": "./build/axios/axios.d.ts", + "default": "./build/axios/axios.js" + }, ".": { - "types": "./build/index.d.ts", - "default": "./build/index.js" + "types": "./build/fetch/fetch.d.ts", + "default": "./build/fetch/fetch.js" } }, "scripts": { - "build": "tsc -b ./tsconfig.json" + "build": "tsc -b ./tsconfig.axios.json ./tsconfig.fetch.json" }, "license": "MIT", "devDependencies": { "@types/node": "^20.11.0", "typescript": "^5.3.3" }, - "dependencies": { + "peerDependencies": { "axios": "^1.6.7" + }, + "peerDependenciesMeta": { + "axios": { + "optional": true + } } } diff --git a/open-api/typescript-sdk/tsconfig.json b/open-api/typescript-sdk/tsconfig.axios.json similarity index 70% rename from open-api/typescript-sdk/tsconfig.json rename to open-api/typescript-sdk/tsconfig.axios.json index 62c64e5be0..77336203c1 100644 --- a/open-api/typescript-sdk/tsconfig.json +++ b/open-api/typescript-sdk/tsconfig.axios.json @@ -1,9 +1,10 @@ { + "include": ["axios.ts", "axios-client/**/*"], "compilerOptions": { "strict": true, "skipLibCheck": true, "declaration": true, - "outDir": "build", + "outDir": "build/axios", "module": "esnext", "moduleResolution": "Bundler", "lib": ["esnext"] diff --git a/open-api/typescript-sdk/tsconfig.fetch.json b/open-api/typescript-sdk/tsconfig.fetch.json new file mode 100644 index 0000000000..c7dc6bfd50 --- /dev/null +++ b/open-api/typescript-sdk/tsconfig.fetch.json @@ -0,0 +1,12 @@ +{ + "include": ["fetch.ts", "fetch-client/**/*"], + "compilerOptions": { + "strict": true, + "skipLibCheck": true, + "declaration": true, + "outDir": "build/fetch", + "module": "esnext", + "moduleResolution": "Bundler", + "lib": ["esnext", "dom"] + } +} diff --git a/web/package-lock.json b/web/package-lock.json index 93c04c47b6..11e62f5342 100644 --- a/web/package-lock.json +++ b/web/package-lock.json @@ -65,12 +65,17 @@ "name": "@immich/sdk", "version": "1.92.1", "license": "MIT", - "dependencies": { - "axios": "^1.6.7" - }, "devDependencies": { "@types/node": "^20.11.0", "typescript": "^5.3.3" + }, + "peerDependencies": { + "axios": "^1.6.7" + }, + "peerDependenciesMeta": { + "axios": { + "optional": true + } } }, "node_modules/@aashutoshrathi/word-wrap": { diff --git a/web/src/api/api.ts b/web/src/api/api.ts index 78228aee1f..72162c5216 100644 --- a/web/src/api/api.ts +++ b/web/src/api/api.ts @@ -25,7 +25,7 @@ import { base, common, configuration, -} from '@immich/sdk'; +} from '@immich/sdk/axios'; import type { ApiParams as ApiParameters } from './types'; class ImmichApi { diff --git a/web/src/api/index.ts b/web/src/api/index.ts index 4d50cff538..886f439d8e 100644 --- a/web/src/api/index.ts +++ b/web/src/api/index.ts @@ -1,3 +1,3 @@ export * from './api'; -export * from '@immich/sdk'; +export * from '@immich/sdk/axios'; export * from './utils'; diff --git a/web/src/api/types.ts b/web/src/api/types.ts index 96baf2f3aa..7a2ae17f67 100644 --- a/web/src/api/types.ts +++ b/web/src/api/types.ts @@ -1,4 +1,4 @@ -import type { Configuration } from '@immich/sdk'; +import type { Configuration } from '@immich/sdk/axios'; /* eslint-disable @typescript-eslint/no-explicit-any */ export type ApiFp = (configuration: Configuration) => Record any>; diff --git a/web/src/api/utils.ts b/web/src/api/utils.ts index a3fed43d32..18b992463e 100644 --- a/web/src/api/utils.ts +++ b/web/src/api/utils.ts @@ -5,7 +5,7 @@ import { } from '../lib/components/shared-components/notification/notification'; import { handleError } from '../lib/utils/handle-error'; import { api } from './api'; -import type { UserResponseDto } from '@immich/sdk'; +import type { UserResponseDto } from '@immich/sdk/axios'; export type ApiError = AxiosError<{ message: string }>; From ce6dc3b7af5a31f31636d4c2e1160c22f53fd0e8 Mon Sep 17 00:00:00 2001 From: Jonathan Jogenfors Date: Tue, 6 Feb 2024 00:40:22 +0100 Subject: [PATCH 014/104] fix(cli): auth file should be chmod 600 (#6925) * wip new tests * test for auth file mode * check perms internally * chore: lint --- cli/package-lock.json | 32 ++++++++++++++--------------- cli/src/commands/base-command.ts | 6 +++--- cli/src/services/session.service.ts | 2 +- cli/test/cli-test-utils.ts | 2 +- cli/test/e2e/login-key.e2e-spec.ts | 26 ++++++++++++++++++++++- 5 files changed, 45 insertions(+), 23 deletions(-) diff --git a/cli/package-lock.json b/cli/package-lock.json index d564d1c28c..4a839dd9e5 100644 --- a/cli/package-lock.json +++ b/cli/package-lock.json @@ -3810,6 +3810,15 @@ "get-func-name": "^2.0.1" } }, + "node_modules/lru-cache": { + "version": "10.2.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.2.0.tgz", + "integrity": "sha512-2bIM8x+VAf6JT4bKAljS1qUWgMsqZRPGJS6FSahIMPVvctcNhyVp7AJu7quxOW9jwkryBReKZY5tY5JYv2n/7Q==", + "dev": true, + "engines": { + "node": "14 || >=16.14" + } + }, "node_modules/magic-string": { "version": "0.30.5", "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.5.tgz", @@ -4182,15 +4191,6 @@ "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/path-scurry/node_modules/lru-cache": { - "version": "10.0.1", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.0.1.tgz", - "integrity": "sha512-IJ4uwUTi2qCccrioU6g9g/5rvvVl13bsdczUUcqbciD9iLr095yj8DQKdObriEvuNSx325N1rV1O0sJFszx75g==", - "dev": true, - "engines": { - "node": "14 || >=16.14" - } - }, "node_modules/path-type": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", @@ -8566,6 +8566,12 @@ "get-func-name": "^2.0.1" } }, + "lru-cache": { + "version": "10.2.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.2.0.tgz", + "integrity": "sha512-2bIM8x+VAf6JT4bKAljS1qUWgMsqZRPGJS6FSahIMPVvctcNhyVp7AJu7quxOW9jwkryBReKZY5tY5JYv2n/7Q==", + "dev": true + }, "magic-string": { "version": "0.30.5", "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.5.tgz", @@ -8834,14 +8840,6 @@ "requires": { "lru-cache": "^9.1.1 || ^10.0.0", "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0" - }, - "dependencies": { - "lru-cache": { - "version": "10.0.1", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.0.1.tgz", - "integrity": "sha512-IJ4uwUTi2qCccrioU6g9g/5rvvVl13bsdczUUcqbciD9iLr095yj8DQKdObriEvuNSx325N1rV1O0sJFszx75g==", - "dev": true - } } }, "path-type": { diff --git a/cli/src/commands/base-command.ts b/cli/src/commands/base-command.ts index 9218da6026..30da229418 100644 --- a/cli/src/commands/base-command.ts +++ b/cli/src/commands/base-command.ts @@ -8,11 +8,11 @@ export abstract class BaseCommand { protected user!: UserResponseDto; protected serverVersion!: ServerVersionResponseDto; - constructor(options: { config?: string }) { - if (!options.config) { + constructor(options: { configDirectory?: string }) { + if (!options.configDirectory) { throw new Error('Config directory is required'); } - this.sessionService = new SessionService(options.config); + this.sessionService = new SessionService(options.configDirectory); } public async connect(): Promise { diff --git a/cli/src/services/session.service.ts b/cli/src/services/session.service.ts index 05df2ec6e3..940cc94d25 100644 --- a/cli/src/services/session.service.ts +++ b/cli/src/services/session.service.ts @@ -82,7 +82,7 @@ export class SessionService { } } - await writeFile(this.authPath, yaml.stringify({ instanceUrl, apiKey })); + await writeFile(this.authPath, yaml.stringify({ instanceUrl, apiKey }), { mode: 0o600 }); console.log('Wrote auth info to ' + this.authPath); diff --git a/cli/test/cli-test-utils.ts b/cli/test/cli-test-utils.ts index 405b7794df..cce81c5ffd 100644 --- a/cli/test/cli-test-utils.ts +++ b/cli/test/cli-test-utils.ts @@ -7,7 +7,7 @@ export const TEST_AUTH_FILE = path.join(TEST_CONFIG_DIR, 'auth.yml'); export const TEST_IMMICH_INSTANCE_URL = 'https://test/api'; export const TEST_IMMICH_API_KEY = 'pNussssKSYo5WasdgalvKJ1n9kdvaasdfbluPg'; -export const CLI_BASE_OPTIONS = { config: TEST_CONFIG_DIR }; +export const CLI_BASE_OPTIONS = { configDirectory: TEST_CONFIG_DIR }; export const setup = async () => { const api = new ImmichApi(process.env.IMMICH_INSTANCE_URL as string, ''); diff --git a/cli/test/e2e/login-key.e2e-spec.ts b/cli/test/e2e/login-key.e2e-spec.ts index 8b215def75..b2c2dcacbb 100644 --- a/cli/test/e2e/login-key.e2e-spec.ts +++ b/cli/test/e2e/login-key.e2e-spec.ts @@ -1,6 +1,8 @@ import { restoreTempFolder, testApp } from '@test-utils'; -import { CLI_BASE_OPTIONS, setup, spyOnConsole } from 'test/cli-test-utils'; +import { CLI_BASE_OPTIONS, TEST_AUTH_FILE, deleteAuthFile, setup, spyOnConsole } from 'test/cli-test-utils'; +import { readFile, stat } from 'node:fs/promises'; import { LoginCommand } from '../../src/commands/login'; +import yaml from 'yaml'; describe(`login-key (e2e)`, () => { let apiKey: string; @@ -20,6 +22,7 @@ describe(`login-key (e2e)`, () => { afterAll(async () => { await testApp.teardown(); await restoreTempFolder(); + deleteAuthFile(); }); beforeEach(async () => { @@ -28,6 +31,8 @@ describe(`login-key (e2e)`, () => { const api = await setup(); apiKey = api.apiKey; + + deleteAuthFile(); }); it('should error when providing an invalid API key', async () => { @@ -39,4 +44,23 @@ describe(`login-key (e2e)`, () => { it('should log in when providing the correct API key', async () => { await new LoginCommand(CLI_BASE_OPTIONS).run(instanceUrl, apiKey); }); + + it('should create an auth file when logging in', async () => { + await new LoginCommand(CLI_BASE_OPTIONS).run(instanceUrl, apiKey); + + const data: string = await readFile(TEST_AUTH_FILE, 'utf8'); + const parsedConfig = yaml.parse(data); + + expect(parsedConfig).toEqual(expect.objectContaining({ instanceUrl, apiKey })); + }); + + it('should create an auth file with chmod 600', async () => { + await new LoginCommand(CLI_BASE_OPTIONS).run(instanceUrl, apiKey); + + const stats = await stat(TEST_AUTH_FILE); + + const mode = (stats.mode & 0o777).toString(8); + + expect(mode).toEqual('600'); + }); }); From 755444e9a41d46e08624c670e977e3d1b673a2b3 Mon Sep 17 00:00:00 2001 From: Jonathan Jogenfors Date: Tue, 6 Feb 2024 11:00:35 +0100 Subject: [PATCH 015/104] chore(cli): use upload api and update documentation (#6927) * use fetch api * bump version * add documentation * revert to using file blob --- cli/package.json | 2 +- cli/src/commands/upload.command.ts | 51 +++++--------------- cli/src/index.ts | 2 +- docs/docs/features/command-line-interface.md | 19 +++++++- 4 files changed, 31 insertions(+), 43 deletions(-) diff --git a/cli/package.json b/cli/package.json index a20070f610..3c3c4a076b 100644 --- a/cli/package.json +++ b/cli/package.json @@ -1,6 +1,6 @@ { "name": "@immich/cli", - "version": "2.0.6", + "version": "2.0.7", "description": "Command Line Interface (CLI) for Immich", "type": "module", "exports": "./dist/index.js", diff --git a/cli/src/commands/upload.command.ts b/cli/src/commands/upload.command.ts index 7933775faf..955d8768f5 100644 --- a/cli/src/commands/upload.command.ts +++ b/cli/src/commands/upload.command.ts @@ -7,14 +7,15 @@ import { basename } from 'node:path'; import { access, constants, stat, unlink } from 'node:fs/promises'; import { createHash } from 'node:crypto'; import os from 'node:os'; +import { UploadFileRequest } from '@immich/sdk'; class Asset { readonly path: string; readonly deviceId!: string; deviceAssetId?: string; - fileCreatedAt?: string; - fileModifiedAt?: string; + fileCreatedAt?: Date; + fileModifiedAt?: Date; sidecarPath?: string; fileSize!: number; albumName?: string; @@ -26,13 +27,13 @@ class Asset { async prepare() { const stats = await stat(this.path); this.deviceAssetId = `${basename(this.path)}-${stats.size}`.replaceAll(/\s+/g, ''); - this.fileCreatedAt = stats.mtime.toISOString(); - this.fileModifiedAt = stats.mtime.toISOString(); + this.fileCreatedAt = stats.mtime; + this.fileModifiedAt = stats.mtime; this.fileSize = stats.size; this.albumName = this.extractAlbumName(); } - async getUploadFormData(): Promise { + async getUploadFileRequest(): Promise { if (!this.deviceAssetId) { throw new Error('Device asset id not set'); } @@ -51,25 +52,15 @@ class Asset { sidecarData = new File([await fs.openAsBlob(sideCarPath)], basename(sideCarPath)); } catch {} - const data: any = { + return { assetData: new File([await fs.openAsBlob(this.path)], basename(this.path)), deviceAssetId: this.deviceAssetId, deviceId: 'CLI', fileCreatedAt: this.fileCreatedAt, fileModifiedAt: this.fileModifiedAt, - isFavorite: String(false), + isFavorite: false, + sidecarData, }; - const formData = new FormData(); - - for (const property in data) { - formData.append(property, data[property]); - } - - if (sidecarData) { - formData.append('sidecarData', sidecarData); - } - - return formData; } async delete(): Promise { @@ -197,10 +188,9 @@ export class UploadCommand extends BaseCommand { if (!skipAsset && !options.dryRun) { if (!skipUpload) { - const formData = await asset.getUploadFormData(); - const response = await this.uploadAsset(formData); - const json = await response.json(); - existingAssetId = json.id; + const fileRequest = await asset.getUploadFileRequest(); + const response = await this.immichApi.assetApi.uploadFile(fileRequest); + existingAssetId = response.id; uploadCounter++; totalSizeUploaded += asset.fileSize; } @@ -258,21 +248,4 @@ export class UploadCommand extends BaseCommand { } } } - - private async uploadAsset(data: FormData): Promise { - const url = this.immichApi.instanceUrl + '/asset/upload'; - - const response = await fetch(url, { - method: 'post', - redirect: 'error', - headers: { - 'x-api-key': this.immichApi.apiKey, - }, - body: data, - }); - if (response.status !== 200 && response.status !== 201) { - throw new Error(await response.text()); - } - return response; - } } diff --git a/cli/src/index.ts b/cli/src/index.ts index 6582b37956..cd16885d32 100644 --- a/cli/src/index.ts +++ b/cli/src/index.ts @@ -24,7 +24,7 @@ program .addOption(new Option('-r, --recursive', 'Recursive').env('IMMICH_RECURSIVE').default(false)) .addOption(new Option('-i, --ignore [paths...]', 'Paths to ignore').env('IMMICH_IGNORE_PATHS')) .addOption(new Option('-h, --skip-hash', "Don't hash files before upload").env('IMMICH_SKIP_HASH').default(false)) - .addOption(new Option('-i, --include-hidden', 'Include hidden folders').env('IMMICH_INCLUDE_HIDDEN').default(false)) + .addOption(new Option('-H, --include-hidden', 'Include hidden folders').env('IMMICH_INCLUDE_HIDDEN').default(false)) .addOption( new Option('-a, --album', 'Automatically create albums based on folder name') .env('IMMICH_AUTO_CREATE_ALBUM') diff --git a/docs/docs/features/command-line-interface.md b/docs/docs/features/command-line-interface.md index ee7ca1c22c..6f16461185 100644 --- a/docs/docs/features/command-line-interface.md +++ b/docs/docs/features/command-line-interface.md @@ -39,10 +39,11 @@ immich ``` Usage: immich [options] [command] -Immich command line interface +Command line interface for Immich Options: -V, --version output the version number + -d, --config Configuration directory (env: IMMICH_CONFIG_DIR) -h, --help display help for command Commands: @@ -69,7 +70,9 @@ Options: -r, --recursive Recursive (default: false, env: IMMICH_RECURSIVE) -i, --ignore [paths...] Paths to ignore (env: IMMICH_IGNORE_PATHS) -h, --skip-hash Don't hash files before upload (default: false, env: IMMICH_SKIP_HASH) + -H, --include-hidden Include hidden folders (default: false, env: IMMICH_INCLUDE_HIDDEN) -a, --album Automatically create albums based on folder name (default: false, env: IMMICH_AUTO_CREATE_ALBUM) + -A, --album-name Add all assets to specified album (env: IMMICH_ALBUM_NAME) -n, --dry-run Don't perform any actions, just show what will be done (default: false, env: IMMICH_DRY_RUN) --delete Delete local assets after upload (env: IMMICH_DELETE_ASSETS) --help display help for command @@ -91,7 +94,7 @@ For instance, immich login-key http://192.168.1.216:2283/api HFEJ38DNSDUEG ``` -This will store your credentials in a file in your home directory. Please keep the file secure, either by performing the logout command after you are done, or deleting it manually. +This will store your credentials in a `auth.yml` file in the configuration directory which defaults to `~/.config/`. The directory can be set with the `-d` option or the environment variable `IMMICH_CONFIG_DIR`. Please keep the file secure, either by performing the logout command after you are done, or deleting it manually. Once you are authenticated, you can upload assets to your Immich server. @@ -123,6 +126,12 @@ You can automatically create albums based on the folder name by passing the `--a immich upload --album --recursive directory/ ``` +You can also choose to upload all assets to a specific album with the `--album-name` option. + +```bash +immich upload --album-name "My summer holiday" --recursive directory/ +``` + It is possible to skip assets matching a glob pattern by passing the `--ignore` option. See [the library documentation](docs/features/libraries.md) on how to use glob patterns. You can add several exclusion patterns if needed. ```bash @@ -133,6 +142,12 @@ immich upload --ignore **/Raw/** --recursive directory/ immich upload --ignore **/Raw/** **/*.tif --recursive directory/ ``` +By default, hidden files are skipped. If you want to include hidden files, use the `--include-hidden` option: + +```bash +immich upload --include-hidden --recursive directory/ +``` + ### Obtain the API Key The API key can be obtained in the user setting panel on the web interface. From 9b3764dbcf1cae882663d1375470f2c00e670bc0 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 6 Feb 2024 10:10:37 +0000 Subject: [PATCH 016/104] chore(deps): update @immich/cli (#6928) * chore(deps): update @immich/cli * npm install --------- Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> Co-authored-by: Jonathan Jogenfors --- cli/package-lock.json | 714 +++++++++++------------------------------- 1 file changed, 176 insertions(+), 538 deletions(-) diff --git a/cli/package-lock.json b/cli/package-lock.json index 4a839dd9e5..03f20f2154 100644 --- a/cli/package-lock.json +++ b/cli/package-lock.json @@ -1,12 +1,12 @@ { "name": "@immich/cli", - "version": "2.0.6", + "version": "2.0.7", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "@immich/cli", - "version": "2.0.6", + "version": "2.0.7", "license": "MIT", "bin": { "immich": "dist/src/index.js" @@ -1290,9 +1290,9 @@ "dev": true }, "node_modules/@types/json-schema": { - "version": "7.0.13", - "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.13.tgz", - "integrity": "sha512-RbSSoHliUbnXj3ny0CNFOoxrIDV6SUGyStHsvDqosw6CkdPV8TtWGlfecuK4ToyMEAql6pzNxgCFKanovUzlgQ==", + "version": "7.0.15", + "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz", + "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==", "dev": true }, "node_modules/@types/mock-fs": { @@ -1305,9 +1305,9 @@ } }, "node_modules/@types/node": { - "version": "20.11.6", - "resolved": "https://registry.npmjs.org/@types/node/-/node-20.11.6.tgz", - "integrity": "sha512-+EOokTnksGVgip2PbYbr3xnR7kZigh4LbybAfBAw5BpnQ+FqBYUsvCEjYd70IXKlbohQ64mzEYmMtlWUY8q//Q==", + "version": "20.11.15", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.11.15.tgz", + "integrity": "sha512-gscmuADZfvNULx1eyirVbr3kVOVZtpQtzKMCZpeSZcN6MfbkRXAR4s9/gsQ4CzxLHw6EStDtKLNtSDL3vbq05A==", "dev": true, "dependencies": { "undici-types": "~5.26.4" @@ -1320,9 +1320,9 @@ "dev": true }, "node_modules/@types/semver": { - "version": "7.5.3", - "resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.5.3.tgz", - "integrity": "sha512-OxepLK9EuNEIPxWNME+C6WwbRAOOI2o2BaQEGzz5Lu2e4Z5eDnEo+/aVEDMIXywoJitJ7xWd641wrGLZdtwRyw==", + "version": "7.5.6", + "resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.5.6.tgz", + "integrity": "sha512-dn1l8LaMea/IjDoHNd9J52uBbInB796CDffS6VdIxvqYCPSG0V0DzHp76GpaWnlhg88uYyPbXCDIowa86ybd5A==", "dev": true }, "node_modules/@types/ssh2": { @@ -1353,16 +1353,16 @@ } }, "node_modules/@typescript-eslint/eslint-plugin": { - "version": "6.19.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-6.19.1.tgz", - "integrity": "sha512-roQScUGFruWod9CEyoV5KlCYrubC/fvG8/1zXuT0WTcxX87GnMMmnksMwSg99lo1xiKrBzw2icsJPMAw1OtKxg==", + "version": "6.20.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-6.20.0.tgz", + "integrity": "sha512-fTwGQUnjhoYHeSF6m5pWNkzmDDdsKELYrOBxhjMrofPqCkoC2k3B2wvGHFxa1CTIqkEn88nlW1HVMztjo2K8Hg==", "dev": true, "dependencies": { "@eslint-community/regexpp": "^4.5.1", - "@typescript-eslint/scope-manager": "6.19.1", - "@typescript-eslint/type-utils": "6.19.1", - "@typescript-eslint/utils": "6.19.1", - "@typescript-eslint/visitor-keys": "6.19.1", + "@typescript-eslint/scope-manager": "6.20.0", + "@typescript-eslint/type-utils": "6.20.0", + "@typescript-eslint/utils": "6.20.0", + "@typescript-eslint/visitor-keys": "6.20.0", "debug": "^4.3.4", "graphemer": "^1.4.0", "ignore": "^5.2.4", @@ -1387,140 +1387,16 @@ } } }, - "node_modules/@typescript-eslint/eslint-plugin/node_modules/@typescript-eslint/scope-manager": { - "version": "6.19.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-6.19.1.tgz", - "integrity": "sha512-4CdXYjKf6/6aKNMSly/BP4iCSOpvMmqtDzRtqFyyAae3z5kkqEjKndR5vDHL8rSuMIIWP8u4Mw4VxLyxZW6D5w==", - "dev": true, - "dependencies": { - "@typescript-eslint/types": "6.19.1", - "@typescript-eslint/visitor-keys": "6.19.1" - }, - "engines": { - "node": "^16.0.0 || >=18.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "node_modules/@typescript-eslint/eslint-plugin/node_modules/@typescript-eslint/types": { - "version": "6.19.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-6.19.1.tgz", - "integrity": "sha512-6+bk6FEtBhvfYvpHsDgAL3uo4BfvnTnoge5LrrCj2eJN8g3IJdLTD4B/jK3Q6vo4Ql/Hoip9I8aB6fF+6RfDqg==", - "dev": true, - "engines": { - "node": "^16.0.0 || >=18.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "node_modules/@typescript-eslint/eslint-plugin/node_modules/@typescript-eslint/typescript-estree": { - "version": "6.19.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-6.19.1.tgz", - "integrity": "sha512-aFdAxuhzBFRWhy+H20nYu19+Km+gFfwNO4TEqyszkMcgBDYQjmPJ61erHxuT2ESJXhlhrO7I5EFIlZ+qGR8oVA==", - "dev": true, - "dependencies": { - "@typescript-eslint/types": "6.19.1", - "@typescript-eslint/visitor-keys": "6.19.1", - "debug": "^4.3.4", - "globby": "^11.1.0", - "is-glob": "^4.0.3", - "minimatch": "9.0.3", - "semver": "^7.5.4", - "ts-api-utils": "^1.0.1" - }, - "engines": { - "node": "^16.0.0 || >=18.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } - } - }, - "node_modules/@typescript-eslint/eslint-plugin/node_modules/@typescript-eslint/utils": { - "version": "6.19.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-6.19.1.tgz", - "integrity": "sha512-JvjfEZuP5WoMqwh9SPAPDSHSg9FBHHGhjPugSRxu5jMfjvBpq5/sGTD+9M9aQ5sh6iJ8AY/Kk/oUYVEMAPwi7w==", - "dev": true, - "dependencies": { - "@eslint-community/eslint-utils": "^4.4.0", - "@types/json-schema": "^7.0.12", - "@types/semver": "^7.5.0", - "@typescript-eslint/scope-manager": "6.19.1", - "@typescript-eslint/types": "6.19.1", - "@typescript-eslint/typescript-estree": "6.19.1", - "semver": "^7.5.4" - }, - "engines": { - "node": "^16.0.0 || >=18.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependencies": { - "eslint": "^7.0.0 || ^8.0.0" - } - }, - "node_modules/@typescript-eslint/eslint-plugin/node_modules/@typescript-eslint/visitor-keys": { - "version": "6.19.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-6.19.1.tgz", - "integrity": "sha512-gkdtIO+xSO/SmI0W68DBg4u1KElmIUo3vXzgHyGPs6cxgB0sa3TlptRAAE0hUY1hM6FcDKEv7aIwiTGm76cXfQ==", - "dev": true, - "dependencies": { - "@typescript-eslint/types": "6.19.1", - "eslint-visitor-keys": "^3.4.1" - }, - "engines": { - "node": "^16.0.0 || >=18.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "node_modules/@typescript-eslint/eslint-plugin/node_modules/brace-expansion": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", - "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", - "dev": true, - "dependencies": { - "balanced-match": "^1.0.0" - } - }, - "node_modules/@typescript-eslint/eslint-plugin/node_modules/minimatch": { - "version": "9.0.3", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.3.tgz", - "integrity": "sha512-RHiac9mvaRw0x3AYRgDC1CxAP7HTcNrrECeA8YYJeWnpo+2Q5CegtZjaotWTWxDG3UeGA1coE05iH1mPjT/2mg==", - "dev": true, - "dependencies": { - "brace-expansion": "^2.0.1" - }, - "engines": { - "node": ">=16 || 14 >=14.17" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, "node_modules/@typescript-eslint/parser": { - "version": "6.19.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-6.19.1.tgz", - "integrity": "sha512-WEfX22ziAh6pRE9jnbkkLGp/4RhTpffr2ZK5bJ18M8mIfA8A+k97U9ZyaXCEJRlmMHh7R9MJZWXp/r73DzINVQ==", + "version": "6.20.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-6.20.0.tgz", + "integrity": "sha512-bYerPDF/H5v6V76MdMYhjwmwgMA+jlPVqjSDq2cRqMi8bP5sR3Z+RLOiOMad3nsnmDVmn2gAFCyNgh/dIrfP/w==", "dev": true, "dependencies": { - "@typescript-eslint/scope-manager": "6.19.1", - "@typescript-eslint/types": "6.19.1", - "@typescript-eslint/typescript-estree": "6.19.1", - "@typescript-eslint/visitor-keys": "6.19.1", + "@typescript-eslint/scope-manager": "6.20.0", + "@typescript-eslint/types": "6.20.0", + "@typescript-eslint/typescript-estree": "6.20.0", + "@typescript-eslint/visitor-keys": "6.20.0", "debug": "^4.3.4" }, "engines": { @@ -1539,14 +1415,14 @@ } } }, - "node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/scope-manager": { - "version": "6.19.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-6.19.1.tgz", - "integrity": "sha512-4CdXYjKf6/6aKNMSly/BP4iCSOpvMmqtDzRtqFyyAae3z5kkqEjKndR5vDHL8rSuMIIWP8u4Mw4VxLyxZW6D5w==", + "node_modules/@typescript-eslint/scope-manager": { + "version": "6.20.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-6.20.0.tgz", + "integrity": "sha512-p4rvHQRDTI1tGGMDFQm+GtxP1ZHyAh64WANVoyEcNMpaTFn3ox/3CcgtIlELnRfKzSs/DwYlDccJEtr3O6qBvA==", "dev": true, "dependencies": { - "@typescript-eslint/types": "6.19.1", - "@typescript-eslint/visitor-keys": "6.19.1" + "@typescript-eslint/types": "6.20.0", + "@typescript-eslint/visitor-keys": "6.20.0" }, "engines": { "node": "^16.0.0 || >=18.0.0" @@ -1556,96 +1432,14 @@ "url": "https://opencollective.com/typescript-eslint" } }, - "node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/types": { - "version": "6.19.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-6.19.1.tgz", - "integrity": "sha512-6+bk6FEtBhvfYvpHsDgAL3uo4BfvnTnoge5LrrCj2eJN8g3IJdLTD4B/jK3Q6vo4Ql/Hoip9I8aB6fF+6RfDqg==", - "dev": true, - "engines": { - "node": "^16.0.0 || >=18.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/typescript-estree": { - "version": "6.19.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-6.19.1.tgz", - "integrity": "sha512-aFdAxuhzBFRWhy+H20nYu19+Km+gFfwNO4TEqyszkMcgBDYQjmPJ61erHxuT2ESJXhlhrO7I5EFIlZ+qGR8oVA==", - "dev": true, - "dependencies": { - "@typescript-eslint/types": "6.19.1", - "@typescript-eslint/visitor-keys": "6.19.1", - "debug": "^4.3.4", - "globby": "^11.1.0", - "is-glob": "^4.0.3", - "minimatch": "9.0.3", - "semver": "^7.5.4", - "ts-api-utils": "^1.0.1" - }, - "engines": { - "node": "^16.0.0 || >=18.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } - } - }, - "node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/visitor-keys": { - "version": "6.19.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-6.19.1.tgz", - "integrity": "sha512-gkdtIO+xSO/SmI0W68DBg4u1KElmIUo3vXzgHyGPs6cxgB0sa3TlptRAAE0hUY1hM6FcDKEv7aIwiTGm76cXfQ==", - "dev": true, - "dependencies": { - "@typescript-eslint/types": "6.19.1", - "eslint-visitor-keys": "^3.4.1" - }, - "engines": { - "node": "^16.0.0 || >=18.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "node_modules/@typescript-eslint/parser/node_modules/brace-expansion": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", - "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", - "dev": true, - "dependencies": { - "balanced-match": "^1.0.0" - } - }, - "node_modules/@typescript-eslint/parser/node_modules/minimatch": { - "version": "9.0.3", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.3.tgz", - "integrity": "sha512-RHiac9mvaRw0x3AYRgDC1CxAP7HTcNrrECeA8YYJeWnpo+2Q5CegtZjaotWTWxDG3UeGA1coE05iH1mPjT/2mg==", - "dev": true, - "dependencies": { - "brace-expansion": "^2.0.1" - }, - "engines": { - "node": ">=16 || 14 >=14.17" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, "node_modules/@typescript-eslint/type-utils": { - "version": "6.19.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-6.19.1.tgz", - "integrity": "sha512-0vdyld3ecfxJuddDjACUvlAeYNrHP/pDeQk2pWBR2ESeEzQhg52DF53AbI9QCBkYE23lgkhLCZNkHn2hEXXYIg==", + "version": "6.20.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-6.20.0.tgz", + "integrity": "sha512-qnSobiJQb1F5JjN0YDRPHruQTrX7ICsmltXhkV536mp4idGAYrIyr47zF/JmkJtEcAVnIz4gUYJ7gOZa6SmN4g==", "dev": true, "dependencies": { - "@typescript-eslint/typescript-estree": "6.19.1", - "@typescript-eslint/utils": "6.19.1", + "@typescript-eslint/typescript-estree": "6.20.0", + "@typescript-eslint/utils": "6.20.0", "debug": "^4.3.4", "ts-api-utils": "^1.0.1" }, @@ -1665,27 +1459,10 @@ } } }, - "node_modules/@typescript-eslint/type-utils/node_modules/@typescript-eslint/scope-manager": { - "version": "6.19.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-6.19.1.tgz", - "integrity": "sha512-4CdXYjKf6/6aKNMSly/BP4iCSOpvMmqtDzRtqFyyAae3z5kkqEjKndR5vDHL8rSuMIIWP8u4Mw4VxLyxZW6D5w==", - "dev": true, - "dependencies": { - "@typescript-eslint/types": "6.19.1", - "@typescript-eslint/visitor-keys": "6.19.1" - }, - "engines": { - "node": "^16.0.0 || >=18.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "node_modules/@typescript-eslint/type-utils/node_modules/@typescript-eslint/types": { - "version": "6.19.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-6.19.1.tgz", - "integrity": "sha512-6+bk6FEtBhvfYvpHsDgAL3uo4BfvnTnoge5LrrCj2eJN8g3IJdLTD4B/jK3Q6vo4Ql/Hoip9I8aB6fF+6RfDqg==", + "node_modules/@typescript-eslint/types": { + "version": "6.20.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-6.20.0.tgz", + "integrity": "sha512-MM9mfZMAhiN4cOEcUOEx+0HmuaW3WBfukBZPCfwSqFnQy0grXYtngKCqpQN339X3RrwtzspWJrpbrupKYUSBXQ==", "dev": true, "engines": { "node": "^16.0.0 || >=18.0.0" @@ -1695,14 +1472,14 @@ "url": "https://opencollective.com/typescript-eslint" } }, - "node_modules/@typescript-eslint/type-utils/node_modules/@typescript-eslint/typescript-estree": { - "version": "6.19.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-6.19.1.tgz", - "integrity": "sha512-aFdAxuhzBFRWhy+H20nYu19+Km+gFfwNO4TEqyszkMcgBDYQjmPJ61erHxuT2ESJXhlhrO7I5EFIlZ+qGR8oVA==", + "node_modules/@typescript-eslint/typescript-estree": { + "version": "6.20.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-6.20.0.tgz", + "integrity": "sha512-RnRya9q5m6YYSpBN7IzKu9FmLcYtErkDkc8/dKv81I9QiLLtVBHrjz+Ev/crAqgMNW2FCsoZF4g2QUylMnJz+g==", "dev": true, "dependencies": { - "@typescript-eslint/types": "6.19.1", - "@typescript-eslint/visitor-keys": "6.19.1", + "@typescript-eslint/types": "6.20.0", + "@typescript-eslint/visitor-keys": "6.20.0", "debug": "^4.3.4", "globby": "^11.1.0", "is-glob": "^4.0.3", @@ -1723,18 +1500,42 @@ } } }, - "node_modules/@typescript-eslint/type-utils/node_modules/@typescript-eslint/utils": { - "version": "6.19.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-6.19.1.tgz", - "integrity": "sha512-JvjfEZuP5WoMqwh9SPAPDSHSg9FBHHGhjPugSRxu5jMfjvBpq5/sGTD+9M9aQ5sh6iJ8AY/Kk/oUYVEMAPwi7w==", + "node_modules/@typescript-eslint/typescript-estree/node_modules/brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/@typescript-eslint/typescript-estree/node_modules/minimatch": { + "version": "9.0.3", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.3.tgz", + "integrity": "sha512-RHiac9mvaRw0x3AYRgDC1CxAP7HTcNrrECeA8YYJeWnpo+2Q5CegtZjaotWTWxDG3UeGA1coE05iH1mPjT/2mg==", + "dev": true, + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/@typescript-eslint/utils": { + "version": "6.20.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-6.20.0.tgz", + "integrity": "sha512-/EKuw+kRu2vAqCoDwDCBtDRU6CTKbUmwwI7SH7AashZ+W+7o8eiyy6V2cdOqN49KsTcASWsC5QeghYuRDTyOOg==", "dev": true, "dependencies": { "@eslint-community/eslint-utils": "^4.4.0", "@types/json-schema": "^7.0.12", "@types/semver": "^7.5.0", - "@typescript-eslint/scope-manager": "6.19.1", - "@typescript-eslint/types": "6.19.1", - "@typescript-eslint/typescript-estree": "6.19.1", + "@typescript-eslint/scope-manager": "6.20.0", + "@typescript-eslint/types": "6.20.0", + "@typescript-eslint/typescript-estree": "6.20.0", "semver": "^7.5.4" }, "engines": { @@ -1748,13 +1549,13 @@ "eslint": "^7.0.0 || ^8.0.0" } }, - "node_modules/@typescript-eslint/type-utils/node_modules/@typescript-eslint/visitor-keys": { - "version": "6.19.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-6.19.1.tgz", - "integrity": "sha512-gkdtIO+xSO/SmI0W68DBg4u1KElmIUo3vXzgHyGPs6cxgB0sa3TlptRAAE0hUY1hM6FcDKEv7aIwiTGm76cXfQ==", + "node_modules/@typescript-eslint/visitor-keys": { + "version": "6.20.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-6.20.0.tgz", + "integrity": "sha512-E8Cp98kRe4gKHjJD4NExXKz/zOJ1A2hhZc+IMVD6i7w4yjIvh6VyuRI0gRtxAsXtoC35uGMaQ9rjI2zJaXDEAw==", "dev": true, "dependencies": { - "@typescript-eslint/types": "6.19.1", + "@typescript-eslint/types": "6.20.0", "eslint-visitor-keys": "^3.4.1" }, "engines": { @@ -1765,30 +1566,6 @@ "url": "https://opencollective.com/typescript-eslint" } }, - "node_modules/@typescript-eslint/type-utils/node_modules/brace-expansion": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", - "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", - "dev": true, - "dependencies": { - "balanced-match": "^1.0.0" - } - }, - "node_modules/@typescript-eslint/type-utils/node_modules/minimatch": { - "version": "9.0.3", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.3.tgz", - "integrity": "sha512-RHiac9mvaRw0x3AYRgDC1CxAP7HTcNrrECeA8YYJeWnpo+2Q5CegtZjaotWTWxDG3UeGA1coE05iH1mPjT/2mg==", - "dev": true, - "dependencies": { - "brace-expansion": "^2.0.1" - }, - "engines": { - "node": ">=16 || 14 >=14.17" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, "node_modules/@ungap/structured-clone": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/@ungap/structured-clone/-/structured-clone-1.2.0.tgz", @@ -3045,9 +2822,9 @@ "dev": true }, "node_modules/fast-glob": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.1.tgz", - "integrity": "sha512-kNFPyjhh5cKjrUltxs+wFx+ZkbRaxxmZ+X0ZU31SOsxCEtP9VPgtq2teZw1DebupL5GmDaNQ6yKMMVcM41iqDg==", + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.2.tgz", + "integrity": "sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow==", "dev": true, "dependencies": { "@nodelib/fs.stat": "^2.0.2", @@ -6633,9 +6410,9 @@ "dev": true }, "@types/json-schema": { - "version": "7.0.13", - "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.13.tgz", - "integrity": "sha512-RbSSoHliUbnXj3ny0CNFOoxrIDV6SUGyStHsvDqosw6CkdPV8TtWGlfecuK4ToyMEAql6pzNxgCFKanovUzlgQ==", + "version": "7.0.15", + "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz", + "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==", "dev": true }, "@types/mock-fs": { @@ -6648,9 +6425,9 @@ } }, "@types/node": { - "version": "20.11.6", - "resolved": "https://registry.npmjs.org/@types/node/-/node-20.11.6.tgz", - "integrity": "sha512-+EOokTnksGVgip2PbYbr3xnR7kZigh4LbybAfBAw5BpnQ+FqBYUsvCEjYd70IXKlbohQ64mzEYmMtlWUY8q//Q==", + "version": "20.11.15", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.11.15.tgz", + "integrity": "sha512-gscmuADZfvNULx1eyirVbr3kVOVZtpQtzKMCZpeSZcN6MfbkRXAR4s9/gsQ4CzxLHw6EStDtKLNtSDL3vbq05A==", "dev": true, "requires": { "undici-types": "~5.26.4" @@ -6663,9 +6440,9 @@ "dev": true }, "@types/semver": { - "version": "7.5.3", - "resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.5.3.tgz", - "integrity": "sha512-OxepLK9EuNEIPxWNME+C6WwbRAOOI2o2BaQEGzz5Lu2e4Z5eDnEo+/aVEDMIXywoJitJ7xWd641wrGLZdtwRyw==", + "version": "7.5.6", + "resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.5.6.tgz", + "integrity": "sha512-dn1l8LaMea/IjDoHNd9J52uBbInB796CDffS6VdIxvqYCPSG0V0DzHp76GpaWnlhg88uYyPbXCDIowa86ybd5A==", "dev": true }, "@types/ssh2": { @@ -6698,156 +6475,81 @@ } }, "@typescript-eslint/eslint-plugin": { - "version": "6.19.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-6.19.1.tgz", - "integrity": "sha512-roQScUGFruWod9CEyoV5KlCYrubC/fvG8/1zXuT0WTcxX87GnMMmnksMwSg99lo1xiKrBzw2icsJPMAw1OtKxg==", + "version": "6.20.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-6.20.0.tgz", + "integrity": "sha512-fTwGQUnjhoYHeSF6m5pWNkzmDDdsKELYrOBxhjMrofPqCkoC2k3B2wvGHFxa1CTIqkEn88nlW1HVMztjo2K8Hg==", "dev": true, "requires": { "@eslint-community/regexpp": "^4.5.1", - "@typescript-eslint/scope-manager": "6.19.1", - "@typescript-eslint/type-utils": "6.19.1", - "@typescript-eslint/utils": "6.19.1", - "@typescript-eslint/visitor-keys": "6.19.1", + "@typescript-eslint/scope-manager": "6.20.0", + "@typescript-eslint/type-utils": "6.20.0", + "@typescript-eslint/utils": "6.20.0", + "@typescript-eslint/visitor-keys": "6.20.0", "debug": "^4.3.4", "graphemer": "^1.4.0", "ignore": "^5.2.4", "natural-compare": "^1.4.0", "semver": "^7.5.4", "ts-api-utils": "^1.0.1" - }, - "dependencies": { - "@typescript-eslint/scope-manager": { - "version": "6.19.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-6.19.1.tgz", - "integrity": "sha512-4CdXYjKf6/6aKNMSly/BP4iCSOpvMmqtDzRtqFyyAae3z5kkqEjKndR5vDHL8rSuMIIWP8u4Mw4VxLyxZW6D5w==", - "dev": true, - "requires": { - "@typescript-eslint/types": "6.19.1", - "@typescript-eslint/visitor-keys": "6.19.1" - } - }, - "@typescript-eslint/types": { - "version": "6.19.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-6.19.1.tgz", - "integrity": "sha512-6+bk6FEtBhvfYvpHsDgAL3uo4BfvnTnoge5LrrCj2eJN8g3IJdLTD4B/jK3Q6vo4Ql/Hoip9I8aB6fF+6RfDqg==", - "dev": true - }, - "@typescript-eslint/typescript-estree": { - "version": "6.19.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-6.19.1.tgz", - "integrity": "sha512-aFdAxuhzBFRWhy+H20nYu19+Km+gFfwNO4TEqyszkMcgBDYQjmPJ61erHxuT2ESJXhlhrO7I5EFIlZ+qGR8oVA==", - "dev": true, - "requires": { - "@typescript-eslint/types": "6.19.1", - "@typescript-eslint/visitor-keys": "6.19.1", - "debug": "^4.3.4", - "globby": "^11.1.0", - "is-glob": "^4.0.3", - "minimatch": "9.0.3", - "semver": "^7.5.4", - "ts-api-utils": "^1.0.1" - } - }, - "@typescript-eslint/utils": { - "version": "6.19.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-6.19.1.tgz", - "integrity": "sha512-JvjfEZuP5WoMqwh9SPAPDSHSg9FBHHGhjPugSRxu5jMfjvBpq5/sGTD+9M9aQ5sh6iJ8AY/Kk/oUYVEMAPwi7w==", - "dev": true, - "requires": { - "@eslint-community/eslint-utils": "^4.4.0", - "@types/json-schema": "^7.0.12", - "@types/semver": "^7.5.0", - "@typescript-eslint/scope-manager": "6.19.1", - "@typescript-eslint/types": "6.19.1", - "@typescript-eslint/typescript-estree": "6.19.1", - "semver": "^7.5.4" - } - }, - "@typescript-eslint/visitor-keys": { - "version": "6.19.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-6.19.1.tgz", - "integrity": "sha512-gkdtIO+xSO/SmI0W68DBg4u1KElmIUo3vXzgHyGPs6cxgB0sa3TlptRAAE0hUY1hM6FcDKEv7aIwiTGm76cXfQ==", - "dev": true, - "requires": { - "@typescript-eslint/types": "6.19.1", - "eslint-visitor-keys": "^3.4.1" - } - }, - "brace-expansion": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", - "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", - "dev": true, - "requires": { - "balanced-match": "^1.0.0" - } - }, - "minimatch": { - "version": "9.0.3", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.3.tgz", - "integrity": "sha512-RHiac9mvaRw0x3AYRgDC1CxAP7HTcNrrECeA8YYJeWnpo+2Q5CegtZjaotWTWxDG3UeGA1coE05iH1mPjT/2mg==", - "dev": true, - "requires": { - "brace-expansion": "^2.0.1" - } - } } }, "@typescript-eslint/parser": { - "version": "6.19.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-6.19.1.tgz", - "integrity": "sha512-WEfX22ziAh6pRE9jnbkkLGp/4RhTpffr2ZK5bJ18M8mIfA8A+k97U9ZyaXCEJRlmMHh7R9MJZWXp/r73DzINVQ==", + "version": "6.20.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-6.20.0.tgz", + "integrity": "sha512-bYerPDF/H5v6V76MdMYhjwmwgMA+jlPVqjSDq2cRqMi8bP5sR3Z+RLOiOMad3nsnmDVmn2gAFCyNgh/dIrfP/w==", "dev": true, "requires": { - "@typescript-eslint/scope-manager": "6.19.1", - "@typescript-eslint/types": "6.19.1", - "@typescript-eslint/typescript-estree": "6.19.1", - "@typescript-eslint/visitor-keys": "6.19.1", + "@typescript-eslint/scope-manager": "6.20.0", + "@typescript-eslint/types": "6.20.0", + "@typescript-eslint/typescript-estree": "6.20.0", + "@typescript-eslint/visitor-keys": "6.20.0", "debug": "^4.3.4" + } + }, + "@typescript-eslint/scope-manager": { + "version": "6.20.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-6.20.0.tgz", + "integrity": "sha512-p4rvHQRDTI1tGGMDFQm+GtxP1ZHyAh64WANVoyEcNMpaTFn3ox/3CcgtIlELnRfKzSs/DwYlDccJEtr3O6qBvA==", + "dev": true, + "requires": { + "@typescript-eslint/types": "6.20.0", + "@typescript-eslint/visitor-keys": "6.20.0" + } + }, + "@typescript-eslint/type-utils": { + "version": "6.20.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-6.20.0.tgz", + "integrity": "sha512-qnSobiJQb1F5JjN0YDRPHruQTrX7ICsmltXhkV536mp4idGAYrIyr47zF/JmkJtEcAVnIz4gUYJ7gOZa6SmN4g==", + "dev": true, + "requires": { + "@typescript-eslint/typescript-estree": "6.20.0", + "@typescript-eslint/utils": "6.20.0", + "debug": "^4.3.4", + "ts-api-utils": "^1.0.1" + } + }, + "@typescript-eslint/types": { + "version": "6.20.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-6.20.0.tgz", + "integrity": "sha512-MM9mfZMAhiN4cOEcUOEx+0HmuaW3WBfukBZPCfwSqFnQy0grXYtngKCqpQN339X3RrwtzspWJrpbrupKYUSBXQ==", + "dev": true + }, + "@typescript-eslint/typescript-estree": { + "version": "6.20.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-6.20.0.tgz", + "integrity": "sha512-RnRya9q5m6YYSpBN7IzKu9FmLcYtErkDkc8/dKv81I9QiLLtVBHrjz+Ev/crAqgMNW2FCsoZF4g2QUylMnJz+g==", + "dev": true, + "requires": { + "@typescript-eslint/types": "6.20.0", + "@typescript-eslint/visitor-keys": "6.20.0", + "debug": "^4.3.4", + "globby": "^11.1.0", + "is-glob": "^4.0.3", + "minimatch": "9.0.3", + "semver": "^7.5.4", + "ts-api-utils": "^1.0.1" }, "dependencies": { - "@typescript-eslint/scope-manager": { - "version": "6.19.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-6.19.1.tgz", - "integrity": "sha512-4CdXYjKf6/6aKNMSly/BP4iCSOpvMmqtDzRtqFyyAae3z5kkqEjKndR5vDHL8rSuMIIWP8u4Mw4VxLyxZW6D5w==", - "dev": true, - "requires": { - "@typescript-eslint/types": "6.19.1", - "@typescript-eslint/visitor-keys": "6.19.1" - } - }, - "@typescript-eslint/types": { - "version": "6.19.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-6.19.1.tgz", - "integrity": "sha512-6+bk6FEtBhvfYvpHsDgAL3uo4BfvnTnoge5LrrCj2eJN8g3IJdLTD4B/jK3Q6vo4Ql/Hoip9I8aB6fF+6RfDqg==", - "dev": true - }, - "@typescript-eslint/typescript-estree": { - "version": "6.19.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-6.19.1.tgz", - "integrity": "sha512-aFdAxuhzBFRWhy+H20nYu19+Km+gFfwNO4TEqyszkMcgBDYQjmPJ61erHxuT2ESJXhlhrO7I5EFIlZ+qGR8oVA==", - "dev": true, - "requires": { - "@typescript-eslint/types": "6.19.1", - "@typescript-eslint/visitor-keys": "6.19.1", - "debug": "^4.3.4", - "globby": "^11.1.0", - "is-glob": "^4.0.3", - "minimatch": "9.0.3", - "semver": "^7.5.4", - "ts-api-utils": "^1.0.1" - } - }, - "@typescript-eslint/visitor-keys": { - "version": "6.19.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-6.19.1.tgz", - "integrity": "sha512-gkdtIO+xSO/SmI0W68DBg4u1KElmIUo3vXzgHyGPs6cxgB0sa3TlptRAAE0hUY1hM6FcDKEv7aIwiTGm76cXfQ==", - "dev": true, - "requires": { - "@typescript-eslint/types": "6.19.1", - "eslint-visitor-keys": "^3.4.1" - } - }, "brace-expansion": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", @@ -6868,93 +6570,29 @@ } } }, - "@typescript-eslint/type-utils": { - "version": "6.19.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-6.19.1.tgz", - "integrity": "sha512-0vdyld3ecfxJuddDjACUvlAeYNrHP/pDeQk2pWBR2ESeEzQhg52DF53AbI9QCBkYE23lgkhLCZNkHn2hEXXYIg==", + "@typescript-eslint/utils": { + "version": "6.20.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-6.20.0.tgz", + "integrity": "sha512-/EKuw+kRu2vAqCoDwDCBtDRU6CTKbUmwwI7SH7AashZ+W+7o8eiyy6V2cdOqN49KsTcASWsC5QeghYuRDTyOOg==", "dev": true, "requires": { - "@typescript-eslint/typescript-estree": "6.19.1", - "@typescript-eslint/utils": "6.19.1", - "debug": "^4.3.4", - "ts-api-utils": "^1.0.1" - }, - "dependencies": { - "@typescript-eslint/scope-manager": { - "version": "6.19.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-6.19.1.tgz", - "integrity": "sha512-4CdXYjKf6/6aKNMSly/BP4iCSOpvMmqtDzRtqFyyAae3z5kkqEjKndR5vDHL8rSuMIIWP8u4Mw4VxLyxZW6D5w==", - "dev": true, - "requires": { - "@typescript-eslint/types": "6.19.1", - "@typescript-eslint/visitor-keys": "6.19.1" - } - }, - "@typescript-eslint/types": { - "version": "6.19.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-6.19.1.tgz", - "integrity": "sha512-6+bk6FEtBhvfYvpHsDgAL3uo4BfvnTnoge5LrrCj2eJN8g3IJdLTD4B/jK3Q6vo4Ql/Hoip9I8aB6fF+6RfDqg==", - "dev": true - }, - "@typescript-eslint/typescript-estree": { - "version": "6.19.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-6.19.1.tgz", - "integrity": "sha512-aFdAxuhzBFRWhy+H20nYu19+Km+gFfwNO4TEqyszkMcgBDYQjmPJ61erHxuT2ESJXhlhrO7I5EFIlZ+qGR8oVA==", - "dev": true, - "requires": { - "@typescript-eslint/types": "6.19.1", - "@typescript-eslint/visitor-keys": "6.19.1", - "debug": "^4.3.4", - "globby": "^11.1.0", - "is-glob": "^4.0.3", - "minimatch": "9.0.3", - "semver": "^7.5.4", - "ts-api-utils": "^1.0.1" - } - }, - "@typescript-eslint/utils": { - "version": "6.19.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-6.19.1.tgz", - "integrity": "sha512-JvjfEZuP5WoMqwh9SPAPDSHSg9FBHHGhjPugSRxu5jMfjvBpq5/sGTD+9M9aQ5sh6iJ8AY/Kk/oUYVEMAPwi7w==", - "dev": true, - "requires": { - "@eslint-community/eslint-utils": "^4.4.0", - "@types/json-schema": "^7.0.12", - "@types/semver": "^7.5.0", - "@typescript-eslint/scope-manager": "6.19.1", - "@typescript-eslint/types": "6.19.1", - "@typescript-eslint/typescript-estree": "6.19.1", - "semver": "^7.5.4" - } - }, - "@typescript-eslint/visitor-keys": { - "version": "6.19.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-6.19.1.tgz", - "integrity": "sha512-gkdtIO+xSO/SmI0W68DBg4u1KElmIUo3vXzgHyGPs6cxgB0sa3TlptRAAE0hUY1hM6FcDKEv7aIwiTGm76cXfQ==", - "dev": true, - "requires": { - "@typescript-eslint/types": "6.19.1", - "eslint-visitor-keys": "^3.4.1" - } - }, - "brace-expansion": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", - "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", - "dev": true, - "requires": { - "balanced-match": "^1.0.0" - } - }, - "minimatch": { - "version": "9.0.3", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.3.tgz", - "integrity": "sha512-RHiac9mvaRw0x3AYRgDC1CxAP7HTcNrrECeA8YYJeWnpo+2Q5CegtZjaotWTWxDG3UeGA1coE05iH1mPjT/2mg==", - "dev": true, - "requires": { - "brace-expansion": "^2.0.1" - } - } + "@eslint-community/eslint-utils": "^4.4.0", + "@types/json-schema": "^7.0.12", + "@types/semver": "^7.5.0", + "@typescript-eslint/scope-manager": "6.20.0", + "@typescript-eslint/types": "6.20.0", + "@typescript-eslint/typescript-estree": "6.20.0", + "semver": "^7.5.4" + } + }, + "@typescript-eslint/visitor-keys": { + "version": "6.20.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-6.20.0.tgz", + "integrity": "sha512-E8Cp98kRe4gKHjJD4NExXKz/zOJ1A2hhZc+IMVD6i7w4yjIvh6VyuRI0gRtxAsXtoC35uGMaQ9rjI2zJaXDEAw==", + "dev": true, + "requires": { + "@typescript-eslint/types": "6.20.0", + "eslint-visitor-keys": "^3.4.1" } }, "@ungap/structured-clone": { @@ -7884,9 +7522,9 @@ "dev": true }, "fast-glob": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.1.tgz", - "integrity": "sha512-kNFPyjhh5cKjrUltxs+wFx+ZkbRaxxmZ+X0ZU31SOsxCEtP9VPgtq2teZw1DebupL5GmDaNQ6yKMMVcM41iqDg==", + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.2.tgz", + "integrity": "sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow==", "dev": true, "requires": { "@nodelib/fs.stat": "^2.0.2", From 31eb4790dc36904c01fdf3bcccf1b97cdb0b3267 Mon Sep 17 00:00:00 2001 From: Jonathan Jogenfors Date: Tue, 6 Feb 2024 12:17:15 +0100 Subject: [PATCH 017/104] feat(cli): dockerize (#6858) * import dockerfile from old cli * build works * rename login command * bump packages * fix login command * chore: remove axios dependency from CLI * move immich script path * can build docker * wip * wip * don't externalize sdk * can run docker * improve entrypoint * can save auth state between runs * add docs * clarify reqs * fix lint * bump alpine to 3.19 * add env files for api key * remove immich cli GHA for now * Update docs/docs/features/command-line-interface.md Co-authored-by: Ben McCann <322311+benmccann@users.noreply.github.com> * remove redundant env variable check * cleanup * speling --------- Co-authored-by: Ben McCann <322311+benmccann@users.noreply.github.com> --- .github/workflows/docker.yml | 3 ++- cli/Dockerfile | 22 +++++++++---------- cli/package-lock.json | 18 +++++++-------- cli/package.json | 4 ++-- .../commands/{login.ts => login.command.ts} | 0 cli/src/index.ts | 11 ++++++---- cli/test/e2e/login-key.e2e-spec.ts | 3 +-- docs/docs/features/command-line-interface.md | 16 ++++++++++++-- 8 files changed, 46 insertions(+), 31 deletions(-) rename cli/src/commands/{login.ts => login.command.ts} (100%) diff --git a/.github/workflows/docker.yml b/.github/workflows/docker.yml index 10ed06510f..a6a6835882 100644 --- a/.github/workflows/docker.yml +++ b/.github/workflows/docker.yml @@ -44,7 +44,7 @@ jobs: platforms: linux/amd64 device: openvino suffix: -openvino - + - image: immich-machine-learning context: machine-learning file: machine-learning/Dockerfile @@ -57,6 +57,7 @@ jobs: file: server/Dockerfile platforms: linux/amd64,linux/arm64 device: cpu + steps: - name: Checkout uses: actions/checkout@v4 diff --git a/cli/Dockerfile b/cli/Dockerfile index 0af3c3cef6..02fffca397 100644 --- a/cli/Dockerfile +++ b/cli/Dockerfile @@ -1,19 +1,19 @@ -FROM ghcr.io/immich-app/base-server-dev:20240130@sha256:a11ac5c56f0ccce1f218954c07c43caadf489557252ba5b9ca1c5977aaa25999 as test +FROM node:20-alpine3.19 as core -WORKDIR /usr/src/app/server -COPY server/package.json server/package-lock.json ./ +WORKDIR /usr/src/open-api/typescript-sdk +COPY open-api/typescript-sdk/package*.json open-api/typescript-sdk/tsconfig*.json ./ RUN npm ci -COPY ./server/ . +COPY open-api/typescript-sdk/ ./ +RUN npm run build + +WORKDIR /usr/src/app -WORKDIR /usr/src/app/cli COPY cli/package.json cli/package-lock.json ./ RUN npm ci -COPY ./cli/ . -FROM ghcr.io/immich-app/base-server-prod:20240130@sha256:ce23a32154540b906df3c971766bcd991561c60331794e0ebb780947ac48113f +COPY cli . +RUN npm run build -VOLUME /usr/src/app/upload +WORKDIR /import -EXPOSE 3001 - -ENTRYPOINT ["tini", "--", "/bin/sh"] +ENTRYPOINT ["node", "/usr/src/app/dist"] \ No newline at end of file diff --git a/cli/package-lock.json b/cli/package-lock.json index 03f20f2154..29216de276 100644 --- a/cli/package-lock.json +++ b/cli/package-lock.json @@ -9,7 +9,7 @@ "version": "2.0.7", "license": "MIT", "bin": { - "immich": "dist/src/index.js" + "immich": "dist/index.js" }, "devDependencies": { "@immich/sdk": "file:../open-api/typescript-sdk", @@ -23,7 +23,7 @@ "@vitest/coverage-v8": "^1.2.2", "byte-size": "^8.1.1", "cli-progress": "^3.12.0", - "commander": "^11.0.0", + "commander": "^12.0.0", "eslint": "^8.56.0", "eslint-config-prettier": "^9.1.0", "eslint-plugin-prettier": "^5.1.3", @@ -2229,12 +2229,12 @@ "dev": true }, "node_modules/commander": { - "version": "11.1.0", - "resolved": "https://registry.npmjs.org/commander/-/commander-11.1.0.tgz", - "integrity": "sha512-yPVavfyCcRhmorC7rWlkHn15b4wDVgVmBA7kV4QVBsF7kv/9TKJAbAXVTxvTnwP8HHKjRCJDClKbciiYS7p0DQ==", + "version": "12.0.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-12.0.0.tgz", + "integrity": "sha512-MwVNWlYjDTtOjX5PiD7o5pK0UrFU/OYgcJfjjK4RaHZETNtjJqrZa9Y9ds88+A+f+d5lv+561eZ+yCKoS3gbAA==", "dev": true, "engines": { - "node": ">=16" + "node": ">=18" } }, "node_modules/compress-commons": { @@ -7078,9 +7078,9 @@ "dev": true }, "commander": { - "version": "11.1.0", - "resolved": "https://registry.npmjs.org/commander/-/commander-11.1.0.tgz", - "integrity": "sha512-yPVavfyCcRhmorC7rWlkHn15b4wDVgVmBA7kV4QVBsF7kv/9TKJAbAXVTxvTnwP8HHKjRCJDClKbciiYS7p0DQ==", + "version": "12.0.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-12.0.0.tgz", + "integrity": "sha512-MwVNWlYjDTtOjX5PiD7o5pK0UrFU/OYgcJfjjK4RaHZETNtjJqrZa9Y9ds88+A+f+d5lv+561eZ+yCKoS3gbAA==", "dev": true }, "compress-commons": { diff --git a/cli/package.json b/cli/package.json index 3c3c4a076b..83451dbe47 100644 --- a/cli/package.json +++ b/cli/package.json @@ -5,7 +5,7 @@ "type": "module", "exports": "./dist/index.js", "bin": { - "immich": "./dist/src/index.js" + "immich": "./dist/index.js" }, "license": "MIT", "keywords": [ @@ -24,7 +24,7 @@ "@vitest/coverage-v8": "^1.2.2", "byte-size": "^8.1.1", "cli-progress": "^3.12.0", - "commander": "^11.0.0", + "commander": "^12.0.0", "eslint": "^8.56.0", "eslint-config-prettier": "^9.1.0", "eslint-plugin-prettier": "^5.1.3", diff --git a/cli/src/commands/login.ts b/cli/src/commands/login.command.ts similarity index 100% rename from cli/src/commands/login.ts rename to cli/src/commands/login.command.ts diff --git a/cli/src/index.ts b/cli/src/index.ts index cd16885d32..eead2b0272 100644 --- a/cli/src/index.ts +++ b/cli/src/index.ts @@ -3,19 +3,22 @@ import { Command, Option } from 'commander'; import path from 'node:path'; import os from 'node:os'; import { version } from '../package.json'; -import { LoginCommand } from './commands/login'; +import { LoginCommand } from './commands/login.command'; import { LogoutCommand } from './commands/logout.command'; import { ServerInfoCommand } from './commands/server-info.command'; import { UploadCommand } from './commands/upload.command'; -const homeDirectory = os.homedir(); -const configDirectory = path.join(homeDirectory, '.config/immich/'); +const defaultConfigDirectory = path.join(os.homedir(), '.config/immich/'); const program = new Command() .name('immich') .version(version) .description('Command line interface for Immich') - .addOption(new Option('-d, --config', 'Configuration directory').env('IMMICH_CONFIG_DIR').default(configDirectory)); + .addOption( + new Option('-d, --config-directory', 'Configuration directory where auth.yml will be stored') + .env('IMMICH_CONFIG_DIR') + .default(defaultConfigDirectory), + ); program .command('upload') diff --git a/cli/test/e2e/login-key.e2e-spec.ts b/cli/test/e2e/login-key.e2e-spec.ts index b2c2dcacbb..9d69579610 100644 --- a/cli/test/e2e/login-key.e2e-spec.ts +++ b/cli/test/e2e/login-key.e2e-spec.ts @@ -1,7 +1,7 @@ import { restoreTempFolder, testApp } from '@test-utils'; import { CLI_BASE_OPTIONS, TEST_AUTH_FILE, deleteAuthFile, setup, spyOnConsole } from 'test/cli-test-utils'; import { readFile, stat } from 'node:fs/promises'; -import { LoginCommand } from '../../src/commands/login'; +import { LoginCommand } from '../../src/commands/login.command'; import yaml from 'yaml'; describe(`login-key (e2e)`, () => { @@ -58,7 +58,6 @@ describe(`login-key (e2e)`, () => { await new LoginCommand(CLI_BASE_OPTIONS).run(instanceUrl, apiKey); const stats = await stat(TEST_AUTH_FILE); - const mode = (stats.mode & 0o777).toString(8); expect(mode).toEqual('600'); diff --git a/docs/docs/features/command-line-interface.md b/docs/docs/features/command-line-interface.md index 6f16461185..304583ebac 100644 --- a/docs/docs/features/command-line-interface.md +++ b/docs/docs/features/command-line-interface.md @@ -15,10 +15,12 @@ If you are looking to import your Google Photos takeout, we recommend this commu ## Requirements -- Node.js 20.0 or above +- Node.js 20 or above - Npm -## Installation +If you can't install node/npm, there is also a Docker version available below. + +## Installation (NPM) ```bash npm i -g @immich/cli @@ -30,6 +32,16 @@ NOTE: if you previously installed the legacy CLI, you will need to uninstall it npm uninstall -g immich ``` +## Installation (Docker) + +If npm is not available on your system you can try the Docker version + +```bash +docker run -it -v "$(pwd)":/import:ro -e IMMICH_API_KEY=https://your-immich-instance/api -e IMMICH_API_KEY=your-api-key ghcr.io/immich-app/immich-cli:latest +``` + +Please modify the `IMMICH_INSTANCE_URL` and `IMMICH_API_KEY` environment variables as suitable. You can also use a Docker env file to store your sensitive API key. + ## Usage ``` From f7d0a8ed0a33ab9dff45dcf1073a2cfc8685868d Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 6 Feb 2024 12:21:24 +0100 Subject: [PATCH 018/104] fix(deps): update dependency fastapi to v0.109.1 [security] (#6923) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- machine-learning/poetry.lock | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/machine-learning/poetry.lock b/machine-learning/poetry.lock index 3ea02acde2..dd84f77c28 100644 --- a/machine-learning/poetry.lock +++ b/machine-learning/poetry.lock @@ -680,22 +680,22 @@ test = ["pytest (>=6)"] [[package]] name = "fastapi" -version = "0.109.0" +version = "0.109.2" description = "FastAPI framework, high performance, easy to learn, fast to code, ready for production" optional = false python-versions = ">=3.8" files = [ - {file = "fastapi-0.109.0-py3-none-any.whl", hash = "sha256:8c77515984cd8e8cfeb58364f8cc7a28f0692088475e2614f7bf03275eba9093"}, - {file = "fastapi-0.109.0.tar.gz", hash = "sha256:b978095b9ee01a5cf49b19f4bc1ac9b8ca83aa076e770ef8fd9af09a2b88d191"}, + {file = "fastapi-0.109.2-py3-none-any.whl", hash = "sha256:2c9bab24667293b501cad8dd388c05240c850b58ec5876ee3283c47d6e1e3a4d"}, + {file = "fastapi-0.109.2.tar.gz", hash = "sha256:f3817eac96fe4f65a2ebb4baa000f394e55f5fccdaf7f75250804bc58f354f73"}, ] [package.dependencies] pydantic = ">=1.7.4,<1.8 || >1.8,<1.8.1 || >1.8.1,<2.0.0 || >2.0.0,<2.0.1 || >2.0.1,<2.1.0 || >2.1.0,<3.0.0" -starlette = ">=0.35.0,<0.36.0" +starlette = ">=0.36.3,<0.37.0" typing-extensions = ">=4.8.0" [package.extras] -all = ["email-validator (>=2.0.0)", "httpx (>=0.23.0)", "itsdangerous (>=1.1.0)", "jinja2 (>=2.11.2)", "orjson (>=3.2.1)", "pydantic-extra-types (>=2.0.0)", "pydantic-settings (>=2.0.0)", "python-multipart (>=0.0.5)", "pyyaml (>=5.3.1)", "ujson (>=4.0.1,!=4.0.2,!=4.1.0,!=4.2.0,!=4.3.0,!=5.0.0,!=5.1.0)", "uvicorn[standard] (>=0.12.0)"] +all = ["email-validator (>=2.0.0)", "httpx (>=0.23.0)", "itsdangerous (>=1.1.0)", "jinja2 (>=2.11.2)", "orjson (>=3.2.1)", "pydantic-extra-types (>=2.0.0)", "pydantic-settings (>=2.0.0)", "python-multipart (>=0.0.7)", "pyyaml (>=5.3.1)", "ujson (>=4.0.1,!=4.0.2,!=4.1.0,!=4.2.0,!=4.3.0,!=5.0.0,!=5.1.0)", "uvicorn[standard] (>=0.12.0)"] [[package]] name = "filelock" @@ -3032,20 +3032,20 @@ files = [ [[package]] name = "starlette" -version = "0.35.1" +version = "0.36.3" description = "The little ASGI library that shines." optional = false python-versions = ">=3.8" files = [ - {file = "starlette-0.35.1-py3-none-any.whl", hash = "sha256:50bbbda9baa098e361f398fda0928062abbaf1f54f4fadcbe17c092a01eb9a25"}, - {file = "starlette-0.35.1.tar.gz", hash = "sha256:3e2639dac3520e4f58734ed22553f950d3f3cb1001cd2eaac4d57e8cdc5f66bc"}, + {file = "starlette-0.36.3-py3-none-any.whl", hash = "sha256:13d429aa93a61dc40bf503e8c801db1f1bca3dc706b10ef2434a36123568f044"}, + {file = "starlette-0.36.3.tar.gz", hash = "sha256:90a671733cfb35771d8cc605e0b679d23b992f8dcfad48cc60b38cb29aeb7080"}, ] [package.dependencies] anyio = ">=3.4.0,<5" [package.extras] -full = ["httpx (>=0.22.0)", "itsdangerous", "jinja2", "python-multipart", "pyyaml"] +full = ["httpx (>=0.22.0)", "itsdangerous", "jinja2", "python-multipart (>=0.0.7)", "pyyaml"] [[package]] name = "sympy" From bb3f8727a3315c35087c2f7a20e9cced10415daf Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 6 Feb 2024 12:25:06 +0100 Subject: [PATCH 019/104] chore(deps): update dependency @types/node to v20.11.15 (#6929) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- open-api/typescript-sdk/package-lock.json | 39 ++++++++++++++++++----- 1 file changed, 31 insertions(+), 8 deletions(-) diff --git a/open-api/typescript-sdk/package-lock.json b/open-api/typescript-sdk/package-lock.json index 1f367d429d..130ce53f02 100644 --- a/open-api/typescript-sdk/package-lock.json +++ b/open-api/typescript-sdk/package-lock.json @@ -8,18 +8,23 @@ "name": "@immich/sdk", "version": "1.92.1", "license": "MIT", - "dependencies": { - "axios": "^1.6.7" - }, "devDependencies": { "@types/node": "^20.11.0", "typescript": "^5.3.3" + }, + "peerDependencies": { + "axios": "^1.6.7" + }, + "peerDependenciesMeta": { + "axios": { + "optional": true + } } }, "node_modules/@types/node": { - "version": "20.11.6", - "resolved": "https://registry.npmjs.org/@types/node/-/node-20.11.6.tgz", - "integrity": "sha512-+EOokTnksGVgip2PbYbr3xnR7kZigh4LbybAfBAw5BpnQ+FqBYUsvCEjYd70IXKlbohQ64mzEYmMtlWUY8q//Q==", + "version": "20.11.15", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.11.15.tgz", + "integrity": "sha512-gscmuADZfvNULx1eyirVbr3kVOVZtpQtzKMCZpeSZcN6MfbkRXAR4s9/gsQ4CzxLHw6EStDtKLNtSDL3vbq05A==", "dev": true, "dependencies": { "undici-types": "~5.26.4" @@ -28,12 +33,16 @@ "node_modules/asynckit": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", - "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==" + "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==", + "optional": true, + "peer": true }, "node_modules/axios": { "version": "1.6.7", "resolved": "https://registry.npmjs.org/axios/-/axios-1.6.7.tgz", "integrity": "sha512-/hDJGff6/c7u0hDkvkGxR/oy6CbCs8ziCsC7SqmhjfozqiJGc8Z11wrv9z9lYfY4K8l+H9TpjcMDX0xOZmx+RA==", + "optional": true, + "peer": true, "dependencies": { "follow-redirects": "^1.15.4", "form-data": "^4.0.0", @@ -44,6 +53,8 @@ "version": "1.0.8", "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", + "optional": true, + "peer": true, "dependencies": { "delayed-stream": "~1.0.0" }, @@ -55,6 +66,8 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==", + "optional": true, + "peer": true, "engines": { "node": ">=0.4.0" } @@ -69,6 +82,8 @@ "url": "https://github.com/sponsors/RubenVerborgh" } ], + "optional": true, + "peer": true, "engines": { "node": ">=4.0" }, @@ -82,6 +97,8 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz", "integrity": "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==", + "optional": true, + "peer": true, "dependencies": { "asynckit": "^0.4.0", "combined-stream": "^1.0.8", @@ -95,6 +112,8 @@ "version": "1.52.0", "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", + "optional": true, + "peer": true, "engines": { "node": ">= 0.6" } @@ -103,6 +122,8 @@ "version": "2.1.35", "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", + "optional": true, + "peer": true, "dependencies": { "mime-db": "1.52.0" }, @@ -113,7 +134,9 @@ "node_modules/proxy-from-env": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz", - "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==" + "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==", + "optional": true, + "peer": true }, "node_modules/typescript": { "version": "5.3.3", From 0169707c855f4e58a616df2662d9258d70984602 Mon Sep 17 00:00:00 2001 From: Ben McCann <322311+benmccann@users.noreply.github.com> Date: Tue, 6 Feb 2024 05:24:52 -0800 Subject: [PATCH 020/104] chore: build API with esnext target (#6926) --- open-api/typescript-sdk/tsconfig.axios.json | 1 + open-api/typescript-sdk/tsconfig.fetch.json | 1 + 2 files changed, 2 insertions(+) diff --git a/open-api/typescript-sdk/tsconfig.axios.json b/open-api/typescript-sdk/tsconfig.axios.json index 77336203c1..9f0d06bbff 100644 --- a/open-api/typescript-sdk/tsconfig.axios.json +++ b/open-api/typescript-sdk/tsconfig.axios.json @@ -1,6 +1,7 @@ { "include": ["axios.ts", "axios-client/**/*"], "compilerOptions": { + "target": "esnext", "strict": true, "skipLibCheck": true, "declaration": true, diff --git a/open-api/typescript-sdk/tsconfig.fetch.json b/open-api/typescript-sdk/tsconfig.fetch.json index c7dc6bfd50..37c633ea10 100644 --- a/open-api/typescript-sdk/tsconfig.fetch.json +++ b/open-api/typescript-sdk/tsconfig.fetch.json @@ -1,6 +1,7 @@ { "include": ["fetch.ts", "fetch-client/**/*"], "compilerOptions": { + "target": "esnext", "strict": true, "skipLibCheck": true, "declaration": true, From 16e85af5645a772cae5bd965fd70058abb93da4e Mon Sep 17 00:00:00 2001 From: Arumugam Jeganathan Date: Tue, 6 Feb 2024 12:33:00 -0500 Subject: [PATCH 021/104] Update command-line-interface.md (#6944) A typo in the command --- docs/docs/features/command-line-interface.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/docs/features/command-line-interface.md b/docs/docs/features/command-line-interface.md index 304583ebac..360b3c3728 100644 --- a/docs/docs/features/command-line-interface.md +++ b/docs/docs/features/command-line-interface.md @@ -37,7 +37,7 @@ npm uninstall -g immich If npm is not available on your system you can try the Docker version ```bash -docker run -it -v "$(pwd)":/import:ro -e IMMICH_API_KEY=https://your-immich-instance/api -e IMMICH_API_KEY=your-api-key ghcr.io/immich-app/immich-cli:latest +docker run -it -v "$(pwd)":/import:ro -e IMMICH_INSTANCE_URL=https://your-immich-instance/api -e IMMICH_API_KEY=your-api-key ghcr.io/immich-app/immich-cli:latest ``` Please modify the `IMMICH_INSTANCE_URL` and `IMMICH_API_KEY` environment variables as suitable. You can also use a Docker env file to store your sensitive API key. From 2d9b9aac4e3f9f66bc90aabc4c68dabba77e6c88 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 6 Feb 2024 21:19:09 +0100 Subject: [PATCH 022/104] chore(deps): update dependency @types/node to v20.11.16 (#6946) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- cli/package-lock.json | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/cli/package-lock.json b/cli/package-lock.json index 29216de276..ba556794cd 100644 --- a/cli/package-lock.json +++ b/cli/package-lock.json @@ -1305,9 +1305,9 @@ } }, "node_modules/@types/node": { - "version": "20.11.15", - "resolved": "https://registry.npmjs.org/@types/node/-/node-20.11.15.tgz", - "integrity": "sha512-gscmuADZfvNULx1eyirVbr3kVOVZtpQtzKMCZpeSZcN6MfbkRXAR4s9/gsQ4CzxLHw6EStDtKLNtSDL3vbq05A==", + "version": "20.11.16", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.11.16.tgz", + "integrity": "sha512-gKb0enTmRCzXSSUJDq6/sPcqrfCv2mkkG6Jt/clpn5eiCbKTY+SgZUxo+p8ZKMof5dCp9vHQUAB7wOUTod22wQ==", "dev": true, "dependencies": { "undici-types": "~5.26.4" @@ -6425,9 +6425,9 @@ } }, "@types/node": { - "version": "20.11.15", - "resolved": "https://registry.npmjs.org/@types/node/-/node-20.11.15.tgz", - "integrity": "sha512-gscmuADZfvNULx1eyirVbr3kVOVZtpQtzKMCZpeSZcN6MfbkRXAR4s9/gsQ4CzxLHw6EStDtKLNtSDL3vbq05A==", + "version": "20.11.16", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.11.16.tgz", + "integrity": "sha512-gKb0enTmRCzXSSUJDq6/sPcqrfCv2mkkG6Jt/clpn5eiCbKTY+SgZUxo+p8ZKMof5dCp9vHQUAB7wOUTod22wQ==", "dev": true, "requires": { "undici-types": "~5.26.4" From 1a644dbc07f0aa0c515c5c0af943c9f5716bda28 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 6 Feb 2024 21:19:21 +0100 Subject: [PATCH 023/104] chore(deps): update dependency @types/node to v20.11.16 (#6947) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- open-api/typescript-sdk/package-lock.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/open-api/typescript-sdk/package-lock.json b/open-api/typescript-sdk/package-lock.json index 130ce53f02..dc9392cabf 100644 --- a/open-api/typescript-sdk/package-lock.json +++ b/open-api/typescript-sdk/package-lock.json @@ -22,9 +22,9 @@ } }, "node_modules/@types/node": { - "version": "20.11.15", - "resolved": "https://registry.npmjs.org/@types/node/-/node-20.11.15.tgz", - "integrity": "sha512-gscmuADZfvNULx1eyirVbr3kVOVZtpQtzKMCZpeSZcN6MfbkRXAR4s9/gsQ4CzxLHw6EStDtKLNtSDL3vbq05A==", + "version": "20.11.16", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.11.16.tgz", + "integrity": "sha512-gKb0enTmRCzXSSUJDq6/sPcqrfCv2mkkG6Jt/clpn5eiCbKTY+SgZUxo+p8ZKMof5dCp9vHQUAB7wOUTod22wQ==", "dev": true, "dependencies": { "undici-types": "~5.26.4" From 3092a72ac5b8f69ab29b2434b5f0802d17e90096 Mon Sep 17 00:00:00 2001 From: Daniel Dietzler <36593685+danieldietzler@users.noreply.github.com> Date: Tue, 6 Feb 2024 22:30:52 +0100 Subject: [PATCH 024/104] chore(web): remove maplibre dependency (#6948) remove maplibre dependency --- web/package-lock.json | 1 - web/package.json | 1 - 2 files changed, 2 deletions(-) diff --git a/web/package-lock.json b/web/package-lock.json index 11e62f5342..451ca61e5a 100644 --- a/web/package-lock.json +++ b/web/package-lock.json @@ -20,7 +20,6 @@ "justified-layout": "^4.1.0", "lodash-es": "^4.17.21", "luxon": "^3.2.1", - "maplibre-gl": "^3.6.0", "socket.io-client": "^4.6.1", "svelte-local-storage-store": "^0.6.0", "svelte-maplibre": "^0.7.0", diff --git a/web/package.json b/web/package.json index 9e4ccf460a..64961251fc 100644 --- a/web/package.json +++ b/web/package.json @@ -68,7 +68,6 @@ "justified-layout": "^4.1.0", "lodash-es": "^4.17.21", "luxon": "^3.2.1", - "maplibre-gl": "^3.6.0", "socket.io-client": "^4.6.1", "svelte-local-storage-store": "^0.6.0", "svelte-maplibre": "^0.7.0", From 61768ce89ec6dfa56e6c8495337b6e8920807f8a Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 6 Feb 2024 17:01:07 -0500 Subject: [PATCH 025/104] chore(deps): update base-image to v20240206 (major) (#6942) chore(deps): update base-image to v20240206 Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- server/Dockerfile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/server/Dockerfile b/server/Dockerfile index 4c9b92d5b6..7132fd6c43 100644 --- a/server/Dockerfile +++ b/server/Dockerfile @@ -1,5 +1,5 @@ # dev build -FROM ghcr.io/immich-app/base-server-dev:20240130@sha256:a11ac5c56f0ccce1f218954c07c43caadf489557252ba5b9ca1c5977aaa25999 as dev +FROM ghcr.io/immich-app/base-server-dev:20240206@sha256:1aa1cd63ef044910c2e0f4d05dbced67cb610536085837e288817b4c965e6b18 as dev RUN apt-get install --no-install-recommends -yqq tini WORKDIR /usr/src/app @@ -40,7 +40,7 @@ RUN npm run build # prod build -FROM ghcr.io/immich-app/base-server-prod:20240130@sha256:ce23a32154540b906df3c971766bcd991561c60331794e0ebb780947ac48113f +FROM ghcr.io/immich-app/base-server-prod:20240206@sha256:c4c19c500babf2900532952bfb60b98a976d7339f9c35059c1320e3c57c5e040 WORKDIR /usr/src/app ENV NODE_ENV=production \ From 4164bcfd0db966c321bc6d3399e2a9af212c84f1 Mon Sep 17 00:00:00 2001 From: Michael Manganiello Date: Tue, 6 Feb 2024 17:03:25 -0500 Subject: [PATCH 026/104] chore(server): Use ChunkedSet in Access repository (#6943) This change simplifies the Access repository methods, by using the `ChunkedSet` decorator. As the methods expect sets, the `chunks` util needed to be fixed, so it returns chunks of the same type it received. Now `chunks` is overloaded, to have proper typing based on the input parameter. --- server/src/domain/domain.util.ts | 16 +- .../infra/repositories/access.repository.ts | 499 ++++++++---------- 2 files changed, 233 insertions(+), 282 deletions(-) diff --git a/server/src/domain/domain.util.ts b/server/src/domain/domain.util.ts index ba5942cea4..43efbce255 100644 --- a/server/src/domain/domain.util.ts +++ b/server/src/domain/domain.util.ts @@ -178,23 +178,25 @@ export function Optional({ nullable, ...validationOptions }: OptionalOptions = { } /** - * Chunks an array or set into smaller arrays of the specified size. + * Chunks an array or set into smaller collections of the same type and specified size. * * @param collection The collection to chunk. * @param size The size of each chunk. */ -export function chunks(collection: Array | Set, size: number): T[][] { +export function chunks(collection: Array, size: number): Array>; +export function chunks(collection: Set, size: number): Array>; +export function chunks(collection: Array | Set, size: number): Array> | Array> { if (collection instanceof Set) { const result = []; - let chunk = []; + let chunk = new Set(); for (const element of collection) { - chunk.push(element); - if (chunk.length === size) { + chunk.add(element); + if (chunk.size === size) { result.push(chunk); - chunk = []; + chunk = new Set(); } } - if (chunk.length > 0) { + if (chunk.size > 0) { result.push(chunk); } return result; diff --git a/server/src/infra/repositories/access.repository.ts b/server/src/infra/repositories/access.repository.ts index cb6469195e..fea1985ced 100644 --- a/server/src/infra/repositories/access.repository.ts +++ b/server/src/infra/repositories/access.repository.ts @@ -1,4 +1,4 @@ -import { IAccessRepository, chunks, setUnion } from '@app/domain'; +import { IAccessRepository } from '@app/domain'; import { InjectRepository } from '@nestjs/typeorm'; import { Brackets, In, Repository } from 'typeorm'; import { @@ -12,7 +12,8 @@ import { SharedLinkEntity, UserTokenEntity, } from '../entities'; -import { DATABASE_PARAMETER_CHUNK_SIZE, DummyValue, GenerateSql } from '../infra.util'; +import { DummyValue, GenerateSql } from '../infra.util'; +import { ChunkedSet } from '../infra.utils'; type IActivityAccess = IAccessRepository['activity']; type IAlbumAccess = IAccessRepository['album']; @@ -30,72 +31,63 @@ class ActivityAccess implements IActivityAccess { ) {} @GenerateSql({ params: [DummyValue.UUID, DummyValue.UUID_SET] }) + @ChunkedSet({ paramIndex: 1 }) async checkOwnerAccess(userId: string, activityIds: Set): Promise> { if (activityIds.size === 0) { return new Set(); } - return Promise.all( - chunks(activityIds, DATABASE_PARAMETER_CHUNK_SIZE).map((idChunk) => - this.activityRepository - .find({ - select: { id: true }, - where: { - id: In(idChunk), - userId, - }, - }) - .then((activities) => new Set(activities.map((activity) => activity.id))), - ), - ).then((results) => setUnion(...results)); + return this.activityRepository + .find({ + select: { id: true }, + where: { + id: In([...activityIds]), + userId, + }, + }) + .then((activities) => new Set(activities.map((activity) => activity.id))); } @GenerateSql({ params: [DummyValue.UUID, DummyValue.UUID_SET] }) + @ChunkedSet({ paramIndex: 1 }) async checkAlbumOwnerAccess(userId: string, activityIds: Set): Promise> { if (activityIds.size === 0) { return new Set(); } - return Promise.all( - chunks(activityIds, DATABASE_PARAMETER_CHUNK_SIZE).map((idChunk) => - this.activityRepository - .find({ - select: { id: true }, - where: { - id: In(idChunk), - album: { - ownerId: userId, - }, - }, - }) - .then((activities) => new Set(activities.map((activity) => activity.id))), - ), - ).then((results) => setUnion(...results)); + return this.activityRepository + .find({ + select: { id: true }, + where: { + id: In([...activityIds]), + album: { + ownerId: userId, + }, + }, + }) + .then((activities) => new Set(activities.map((activity) => activity.id))); } @GenerateSql({ params: [DummyValue.UUID, DummyValue.UUID_SET] }) + @ChunkedSet({ paramIndex: 1 }) async checkCreateAccess(userId: string, albumIds: Set): Promise> { if (albumIds.size === 0) { return new Set(); } - return Promise.all( - chunks(albumIds, DATABASE_PARAMETER_CHUNK_SIZE).map((idChunk) => - this.albumRepository - .createQueryBuilder('album') - .select('album.id') - .leftJoin('album.sharedUsers', 'sharedUsers') - .where('album.id IN (:...albumIds)', { albumIds: idChunk }) - .andWhere('album.isActivityEnabled = true') - .andWhere( - new Brackets((qb) => { - qb.where('album.ownerId = :userId', { userId }).orWhere('sharedUsers.id = :userId', { userId }); - }), - ) - .getMany() - .then((albums) => new Set(albums.map((album) => album.id))), - ), - ).then((results) => setUnion(...results)); + return this.albumRepository + .createQueryBuilder('album') + .select('album.id') + .leftJoin('album.sharedUsers', 'sharedUsers') + .where('album.id IN (:...albumIds)', { albumIds: [...albumIds] }) + .andWhere('album.isActivityEnabled = true') + .andWhere( + new Brackets((qb) => { + qb.where('album.ownerId = :userId', { userId }).orWhere('sharedUsers.id = :userId', { userId }); + }), + ) + .getMany() + .then((albums) => new Set(albums.map((album) => album.id))); } } @@ -106,71 +98,61 @@ class AlbumAccess implements IAlbumAccess { ) {} @GenerateSql({ params: [DummyValue.UUID, DummyValue.UUID_SET] }) + @ChunkedSet({ paramIndex: 1 }) async checkOwnerAccess(userId: string, albumIds: Set): Promise> { if (albumIds.size === 0) { return new Set(); } - return Promise.all( - chunks(albumIds, DATABASE_PARAMETER_CHUNK_SIZE).map((idChunk) => - this.albumRepository - .find({ - select: { id: true }, - where: { - id: In(idChunk), - ownerId: userId, - }, - }) - .then((albums) => new Set(albums.map((album) => album.id))), - ), - ).then((results) => setUnion(...results)); + return this.albumRepository + .find({ + select: { id: true }, + where: { + id: In([...albumIds]), + ownerId: userId, + }, + }) + .then((albums) => new Set(albums.map((album) => album.id))); } @GenerateSql({ params: [DummyValue.UUID, DummyValue.UUID_SET] }) + @ChunkedSet({ paramIndex: 1 }) async checkSharedAlbumAccess(userId: string, albumIds: Set): Promise> { if (albumIds.size === 0) { return new Set(); } - return Promise.all( - chunks(albumIds, DATABASE_PARAMETER_CHUNK_SIZE).map((idChunk) => - this.albumRepository - .find({ - select: { id: true }, - where: { - id: In(idChunk), - sharedUsers: { - id: userId, - }, - }, - }) - .then((albums) => new Set(albums.map((album) => album.id))), - ), - ).then((results) => setUnion(...results)); + return this.albumRepository + .find({ + select: { id: true }, + where: { + id: In([...albumIds]), + sharedUsers: { + id: userId, + }, + }, + }) + .then((albums) => new Set(albums.map((album) => album.id))); } @GenerateSql({ params: [DummyValue.UUID, DummyValue.UUID_SET] }) + @ChunkedSet({ paramIndex: 1 }) async checkSharedLinkAccess(sharedLinkId: string, albumIds: Set): Promise> { if (albumIds.size === 0) { return new Set(); } - return Promise.all( - chunks(albumIds, DATABASE_PARAMETER_CHUNK_SIZE).map((idChunk) => - this.sharedLinkRepository - .find({ - select: { albumId: true }, - where: { - id: sharedLinkId, - albumId: In(idChunk), - }, - }) - .then( - (sharedLinks) => - new Set(sharedLinks.flatMap((sharedLink) => (sharedLink.albumId ? [sharedLink.albumId] : []))), - ), - ), - ).then((results) => setUnion(...results)); + return this.sharedLinkRepository + .find({ + select: { albumId: true }, + where: { + id: sharedLinkId, + albumId: In([...albumIds]), + }, + }) + .then( + (sharedLinks) => new Set(sharedLinks.flatMap((sharedLink) => (sharedLink.albumId ? [sharedLink.albumId] : []))), + ); } } @@ -183,132 +165,120 @@ class AssetAccess implements IAssetAccess { ) {} @GenerateSql({ params: [DummyValue.UUID, DummyValue.UUID_SET] }) + @ChunkedSet({ paramIndex: 1 }) async checkAlbumAccess(userId: string, assetIds: Set): Promise> { if (assetIds.size === 0) { return new Set(); } - return Promise.all( - chunks(assetIds, DATABASE_PARAMETER_CHUNK_SIZE).map((idChunk) => - this.albumRepository - .createQueryBuilder('album') - .innerJoin('album.assets', 'asset') - .leftJoin('album.sharedUsers', 'sharedUsers') - .select('asset.id', 'assetId') - .addSelect('asset.livePhotoVideoId', 'livePhotoVideoId') - .where('array["asset"."id", "asset"."livePhotoVideoId"] && array[:...assetIds]::uuid[]', { - assetIds: idChunk, - }) - .andWhere( - new Brackets((qb) => { - qb.where('album.ownerId = :userId', { userId }).orWhere('sharedUsers.id = :userId', { userId }); - }), - ) - .getRawMany() - .then((rows) => { - const allowedIds = new Set(); - for (const row of rows) { - if (row.assetId && assetIds.has(row.assetId)) { - allowedIds.add(row.assetId); - } - if (row.livePhotoVideoId && assetIds.has(row.livePhotoVideoId)) { - allowedIds.add(row.livePhotoVideoId); - } - } - return allowedIds; - }), - ), - ).then((results) => setUnion(...results)); + return this.albumRepository + .createQueryBuilder('album') + .innerJoin('album.assets', 'asset') + .leftJoin('album.sharedUsers', 'sharedUsers') + .select('asset.id', 'assetId') + .addSelect('asset.livePhotoVideoId', 'livePhotoVideoId') + .where('array["asset"."id", "asset"."livePhotoVideoId"] && array[:...assetIds]::uuid[]', { + assetIds: [...assetIds], + }) + .andWhere( + new Brackets((qb) => { + qb.where('album.ownerId = :userId', { userId }).orWhere('sharedUsers.id = :userId', { userId }); + }), + ) + .getRawMany() + .then((rows) => { + const allowedIds = new Set(); + for (const row of rows) { + if (row.assetId && assetIds.has(row.assetId)) { + allowedIds.add(row.assetId); + } + if (row.livePhotoVideoId && assetIds.has(row.livePhotoVideoId)) { + allowedIds.add(row.livePhotoVideoId); + } + } + return allowedIds; + }); } @GenerateSql({ params: [DummyValue.UUID, DummyValue.UUID_SET] }) + @ChunkedSet({ paramIndex: 1 }) async checkOwnerAccess(userId: string, assetIds: Set): Promise> { if (assetIds.size === 0) { return new Set(); } - return Promise.all( - chunks(assetIds, DATABASE_PARAMETER_CHUNK_SIZE).map((idChunk) => - this.assetRepository - .find({ - select: { id: true }, - where: { - id: In(idChunk), - ownerId: userId, - }, - withDeleted: true, - }) - .then((assets) => new Set(assets.map((asset) => asset.id))), - ), - ).then((results) => setUnion(...results)); + return this.assetRepository + .find({ + select: { id: true }, + where: { + id: In([...assetIds]), + ownerId: userId, + }, + withDeleted: true, + }) + .then((assets) => new Set(assets.map((asset) => asset.id))); } @GenerateSql({ params: [DummyValue.UUID, DummyValue.UUID_SET] }) + @ChunkedSet({ paramIndex: 1 }) async checkPartnerAccess(userId: string, assetIds: Set): Promise> { if (assetIds.size === 0) { return new Set(); } - return Promise.all( - chunks(assetIds, DATABASE_PARAMETER_CHUNK_SIZE).map((idChunk) => - this.partnerRepository - .createQueryBuilder('partner') - .innerJoin('partner.sharedBy', 'sharedBy') - .innerJoin('sharedBy.assets', 'asset') - .select('asset.id', 'assetId') - .where('partner.sharedWithId = :userId', { userId }) - .andWhere('asset.id IN (:...assetIds)', { assetIds: idChunk }) - .getRawMany() - .then((rows) => new Set(rows.map((row) => row.assetId))), - ), - ).then((results) => setUnion(...results)); + return this.partnerRepository + .createQueryBuilder('partner') + .innerJoin('partner.sharedBy', 'sharedBy') + .innerJoin('sharedBy.assets', 'asset') + .select('asset.id', 'assetId') + .where('partner.sharedWithId = :userId', { userId }) + .andWhere('asset.id IN (:...assetIds)', { assetIds: [...assetIds] }) + .getRawMany() + .then((rows) => new Set(rows.map((row) => row.assetId))); } @GenerateSql({ params: [DummyValue.UUID, DummyValue.UUID_SET] }) + @ChunkedSet({ paramIndex: 1 }) async checkSharedLinkAccess(sharedLinkId: string, assetIds: Set): Promise> { if (assetIds.size === 0) { return new Set(); } - return Promise.all( - chunks(assetIds, DATABASE_PARAMETER_CHUNK_SIZE).map((idChunk) => - this.sharedLinkRepository - .createQueryBuilder('sharedLink') - .leftJoin('sharedLink.album', 'album') - .leftJoin('sharedLink.assets', 'assets') - .leftJoin('album.assets', 'albumAssets') - .select('assets.id', 'assetId') - .addSelect('albumAssets.id', 'albumAssetId') - .addSelect('assets.livePhotoVideoId', 'assetLivePhotoVideoId') - .addSelect('albumAssets.livePhotoVideoId', 'albumAssetLivePhotoVideoId') - .where('sharedLink.id = :sharedLinkId', { sharedLinkId }) - .andWhere( - 'array["assets"."id", "assets"."livePhotoVideoId", "albumAssets"."id", "albumAssets"."livePhotoVideoId"] && array[:...assetIds]::uuid[]', - { - assetIds: idChunk, - }, - ) - .getRawMany() - .then((rows) => { - const allowedIds = new Set(); - for (const row of rows) { - if (row.assetId && assetIds.has(row.assetId)) { - allowedIds.add(row.assetId); - } - if (row.assetLivePhotoVideoId && assetIds.has(row.assetLivePhotoVideoId)) { - allowedIds.add(row.assetLivePhotoVideoId); - } - if (row.albumAssetId && assetIds.has(row.albumAssetId)) { - allowedIds.add(row.albumAssetId); - } - if (row.albumAssetLivePhotoVideoId && assetIds.has(row.albumAssetLivePhotoVideoId)) { - allowedIds.add(row.albumAssetLivePhotoVideoId); - } - } - return allowedIds; - }), - ), - ).then((results) => setUnion(...results)); + return this.sharedLinkRepository + .createQueryBuilder('sharedLink') + .leftJoin('sharedLink.album', 'album') + .leftJoin('sharedLink.assets', 'assets') + .leftJoin('album.assets', 'albumAssets') + .select('assets.id', 'assetId') + .addSelect('albumAssets.id', 'albumAssetId') + .addSelect('assets.livePhotoVideoId', 'assetLivePhotoVideoId') + .addSelect('albumAssets.livePhotoVideoId', 'albumAssetLivePhotoVideoId') + .where('sharedLink.id = :sharedLinkId', { sharedLinkId }) + .andWhere( + 'array["assets"."id", "assets"."livePhotoVideoId", "albumAssets"."id", "albumAssets"."livePhotoVideoId"] && array[:...assetIds]::uuid[]', + { + assetIds: [...assetIds], + }, + ) + .getRawMany() + .then((rows) => { + const allowedIds = new Set(); + for (const row of rows) { + if (row.assetId && assetIds.has(row.assetId)) { + allowedIds.add(row.assetId); + } + if (row.assetLivePhotoVideoId && assetIds.has(row.assetLivePhotoVideoId)) { + allowedIds.add(row.assetLivePhotoVideoId); + } + if (row.albumAssetId && assetIds.has(row.albumAssetId)) { + allowedIds.add(row.albumAssetId); + } + if (row.albumAssetLivePhotoVideoId && assetIds.has(row.albumAssetLivePhotoVideoId)) { + allowedIds.add(row.albumAssetLivePhotoVideoId); + } + } + return allowedIds; + }); } } @@ -316,24 +286,21 @@ class AuthDeviceAccess implements IAuthDeviceAccess { constructor(private tokenRepository: Repository) {} @GenerateSql({ params: [DummyValue.UUID, DummyValue.UUID_SET] }) + @ChunkedSet({ paramIndex: 1 }) async checkOwnerAccess(userId: string, deviceIds: Set): Promise> { if (deviceIds.size === 0) { return new Set(); } - return Promise.all( - chunks(deviceIds, DATABASE_PARAMETER_CHUNK_SIZE).map((idChunk) => - this.tokenRepository - .find({ - select: { id: true }, - where: { - userId, - id: In(idChunk), - }, - }) - .then((tokens) => new Set(tokens.map((token) => token.id))), - ), - ).then((results) => setUnion(...results)); + return this.tokenRepository + .find({ + select: { id: true }, + where: { + userId, + id: In([...deviceIds]), + }, + }) + .then((tokens) => new Set(tokens.map((token) => token.id))); } } @@ -344,43 +311,37 @@ class LibraryAccess implements ILibraryAccess { ) {} @GenerateSql({ params: [DummyValue.UUID, DummyValue.UUID_SET] }) + @ChunkedSet({ paramIndex: 1 }) async checkOwnerAccess(userId: string, libraryIds: Set): Promise> { if (libraryIds.size === 0) { return new Set(); } - return Promise.all( - chunks(libraryIds, DATABASE_PARAMETER_CHUNK_SIZE).map((idChunk) => - this.libraryRepository - .find({ - select: { id: true }, - where: { - id: In(idChunk), - ownerId: userId, - }, - }) - .then((libraries) => new Set(libraries.map((library) => library.id))), - ), - ).then((results) => setUnion(...results)); + return this.libraryRepository + .find({ + select: { id: true }, + where: { + id: In([...libraryIds]), + ownerId: userId, + }, + }) + .then((libraries) => new Set(libraries.map((library) => library.id))); } @GenerateSql({ params: [DummyValue.UUID, DummyValue.UUID_SET] }) + @ChunkedSet({ paramIndex: 1 }) async checkPartnerAccess(userId: string, partnerIds: Set): Promise> { if (partnerIds.size === 0) { return new Set(); } - return Promise.all( - chunks(partnerIds, DATABASE_PARAMETER_CHUNK_SIZE).map((idChunk) => - this.partnerRepository - .createQueryBuilder('partner') - .select('partner.sharedById') - .where('partner.sharedById IN (:...partnerIds)', { partnerIds: idChunk }) - .andWhere('partner.sharedWithId = :userId', { userId }) - .getMany() - .then((partners) => new Set(partners.map((partner) => partner.sharedById))), - ), - ).then((results) => setUnion(...results)); + return this.partnerRepository + .createQueryBuilder('partner') + .select('partner.sharedById') + .where('partner.sharedById IN (:...partnerIds)', { partnerIds: [...partnerIds] }) + .andWhere('partner.sharedWithId = :userId', { userId }) + .getMany() + .then((partners) => new Set(partners.map((partner) => partner.sharedById))); } } @@ -388,22 +349,19 @@ class TimelineAccess implements ITimelineAccess { constructor(private partnerRepository: Repository) {} @GenerateSql({ params: [DummyValue.UUID, DummyValue.UUID_SET] }) + @ChunkedSet({ paramIndex: 1 }) async checkPartnerAccess(userId: string, partnerIds: Set): Promise> { if (partnerIds.size === 0) { return new Set(); } - return Promise.all( - chunks(partnerIds, DATABASE_PARAMETER_CHUNK_SIZE).map((idChunk) => - this.partnerRepository - .createQueryBuilder('partner') - .select('partner.sharedById') - .where('partner.sharedById IN (:...partnerIds)', { partnerIds: idChunk }) - .andWhere('partner.sharedWithId = :userId', { userId }) - .getMany() - .then((partners) => new Set(partners.map((partner) => partner.sharedById))), - ), - ).then((results) => setUnion(...results)); + return this.partnerRepository + .createQueryBuilder('partner') + .select('partner.sharedById') + .where('partner.sharedById IN (:...partnerIds)', { partnerIds: [...partnerIds] }) + .andWhere('partner.sharedWithId = :userId', { userId }) + .getMany() + .then((partners) => new Set(partners.map((partner) => partner.sharedById))); } } @@ -414,47 +372,41 @@ class PersonAccess implements IPersonAccess { ) {} @GenerateSql({ params: [DummyValue.UUID, DummyValue.UUID_SET] }) + @ChunkedSet({ paramIndex: 1 }) async checkOwnerAccess(userId: string, personIds: Set): Promise> { if (personIds.size === 0) { return new Set(); } - return Promise.all( - chunks(personIds, DATABASE_PARAMETER_CHUNK_SIZE).map((idChunk) => - this.personRepository - .find({ - select: { id: true }, - where: { - id: In(idChunk), - ownerId: userId, - }, - }) - .then((persons) => new Set(persons.map((person) => person.id))), - ), - ).then((results) => setUnion(...results)); + return this.personRepository + .find({ + select: { id: true }, + where: { + id: In([...personIds]), + ownerId: userId, + }, + }) + .then((persons) => new Set(persons.map((person) => person.id))); } @GenerateSql({ params: [DummyValue.UUID, DummyValue.UUID_SET] }) + @ChunkedSet({ paramIndex: 1 }) async checkFaceOwnerAccess(userId: string, assetFaceIds: Set): Promise> { if (assetFaceIds.size === 0) { return new Set(); } - return Promise.all( - chunks(assetFaceIds, DATABASE_PARAMETER_CHUNK_SIZE).map((idChunk) => - this.assetFaceRepository - .find({ - select: { id: true }, - where: { - id: In(idChunk), - asset: { - ownerId: userId, - }, - }, - }) - .then((faces) => new Set(faces.map((face) => face.id))), - ), - ).then((results) => setUnion(...results)); + return this.assetFaceRepository + .find({ + select: { id: true }, + where: { + id: In([...assetFaceIds]), + asset: { + ownerId: userId, + }, + }, + }) + .then((faces) => new Set(faces.map((face) => face.id))); } } @@ -462,22 +414,19 @@ class PartnerAccess implements IPartnerAccess { constructor(private partnerRepository: Repository) {} @GenerateSql({ params: [DummyValue.UUID, DummyValue.UUID_SET] }) + @ChunkedSet({ paramIndex: 1 }) async checkUpdateAccess(userId: string, partnerIds: Set): Promise> { if (partnerIds.size === 0) { return new Set(); } - return Promise.all( - chunks(partnerIds, DATABASE_PARAMETER_CHUNK_SIZE).map((idChunk) => - this.partnerRepository - .createQueryBuilder('partner') - .select('partner.sharedById') - .where('partner.sharedById IN (:...partnerIds)', { partnerIds: idChunk }) - .andWhere('partner.sharedWithId = :userId', { userId }) - .getMany() - .then((partners) => new Set(partners.map((partner) => partner.sharedById))), - ), - ).then((results) => setUnion(...results)); + return this.partnerRepository + .createQueryBuilder('partner') + .select('partner.sharedById') + .where('partner.sharedById IN (:...partnerIds)', { partnerIds: [...partnerIds] }) + .andWhere('partner.sharedWithId = :userId', { userId }) + .getMany() + .then((partners) => new Set(partners.map((partner) => partner.sharedById))); } } From 8c60c21fe0c61ed723b4105efabe15999216fddb Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 6 Feb 2024 17:05:23 -0500 Subject: [PATCH 027/104] chore(deps): update web (#6933) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- web/package-lock.json | 220 +++++++++++++++++++++--------------------- 1 file changed, 110 insertions(+), 110 deletions(-) diff --git a/web/package-lock.json b/web/package-lock.json index 451ca61e5a..8ed9df2c72 100644 --- a/web/package-lock.json +++ b/web/package-lock.json @@ -949,22 +949,22 @@ } }, "node_modules/@floating-ui/core": { - "version": "1.5.3", - "resolved": "https://registry.npmjs.org/@floating-ui/core/-/core-1.5.3.tgz", - "integrity": "sha512-O0WKDOo0yhJuugCx6trZQj5jVJ9yR0ystG2JaNAemYUWce+pmM6WUEFIibnWyEJKdrDxhm75NoSRME35FNaM/Q==", + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/@floating-ui/core/-/core-1.6.0.tgz", + "integrity": "sha512-PcF++MykgmTj3CIyOQbKA/hDzOAiqI3mhuoN44WRCopIs1sgoDoU4oty4Jtqaj/y3oDU6fnVSm4QG0a3t5i0+g==", "dev": true, "dependencies": { - "@floating-ui/utils": "^0.2.0" + "@floating-ui/utils": "^0.2.1" } }, "node_modules/@floating-ui/dom": { - "version": "1.5.4", - "resolved": "https://registry.npmjs.org/@floating-ui/dom/-/dom-1.5.4.tgz", - "integrity": "sha512-jByEsHIY+eEdCjnTVu+E3ephzTOzkQ8hgUfGwos+bg7NlH33Zc5uO+QHz1mrQUOgIKKDD1RtS201P9NvAfq3XQ==", + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/@floating-ui/dom/-/dom-1.6.1.tgz", + "integrity": "sha512-iA8qE43/H5iGozC3W0YSnVSW42Vh522yyM1gj+BqRwVsTNOyr231PsXDaV04yT39PsO0QL2QpbI/M0ZaLUQgRQ==", "dev": true, "dependencies": { - "@floating-ui/core": "^1.5.3", - "@floating-ui/utils": "^0.2.0" + "@floating-ui/core": "^1.6.0", + "@floating-ui/utils": "^0.2.1" } }, "node_modules/@floating-ui/utils": { @@ -1420,12 +1420,12 @@ } }, "node_modules/@sveltejs/vite-plugin-svelte": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/@sveltejs/vite-plugin-svelte/-/vite-plugin-svelte-3.0.1.tgz", - "integrity": "sha512-CGURX6Ps+TkOovK6xV+Y2rn8JKa8ZPUHPZ/NKgCxAmgBrXReavzFl8aOSCj3kQ1xqT7yGJj53hjcV/gqwDAaWA==", + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/@sveltejs/vite-plugin-svelte/-/vite-plugin-svelte-3.0.2.tgz", + "integrity": "sha512-MpmF/cju2HqUls50WyTHQBZUV3ovV/Uk8k66AN2gwHogNAG8wnW8xtZDhzNBsFJJuvmq1qnzA5kE7YfMJNFv2Q==", "dev": true, "dependencies": { - "@sveltejs/vite-plugin-svelte-inspector": "^2.0.0-next.0 || ^2.0.0", + "@sveltejs/vite-plugin-svelte-inspector": "^2.0.0", "debug": "^4.3.4", "deepmerge": "^4.3.1", "kleur": "^4.1.5", @@ -1557,9 +1557,9 @@ } }, "node_modules/@testing-library/jest-dom": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/@testing-library/jest-dom/-/jest-dom-6.3.0.tgz", - "integrity": "sha512-hJVIrkFizEQxoWsGBlycTcQhrpoCH4DhXfrnHFFXgkx3Xdm15zycsq5Ep+vpw4W8S0NJa8cxDHcuJib+1tEbhg==", + "version": "6.4.1", + "resolved": "https://registry.npmjs.org/@testing-library/jest-dom/-/jest-dom-6.4.1.tgz", + "integrity": "sha512-Z7qMM3J2Zw5H/nC2/5CYx5YcuaD56JmDFKNIozZ89VIo6o6Y9FMhssics4e2madEKYDNEpZz3+glPGz0yWMOag==", "dev": true, "dependencies": { "@adobe/css-tools": "^4.3.2", @@ -1675,9 +1675,9 @@ } }, "node_modules/@testing-library/svelte": { - "version": "4.0.6", - "resolved": "https://registry.npmjs.org/@testing-library/svelte/-/svelte-4.0.6.tgz", - "integrity": "sha512-4Niit+F/V3/AC03+/hsTrUJjXeoLFgd2KYjlz9nKFVELZR0dApHtc+tILe7NHiBctTAKTEzoM2VDLn1mBOqn3w==", + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/@testing-library/svelte/-/svelte-4.1.0.tgz", + "integrity": "sha512-MJqe7x9WowkiAVdk9mvazEC2ktFZdmK2OqFVoO557PC37aBemQ4ozqdK3yrG34Zg9kuln3qgTVeLSh08e69AMw==", "dev": true, "dependencies": { "@testing-library/dom": "^9.3.1" @@ -1816,16 +1816,16 @@ "integrity": "sha512-HVOsSRTQYx3zpVl0c0FBmmmcY/60BkQLzVnpE9M1aG4f2Z0aKlBWfj4XZ2zr++XNBfkQWYcwhGlmuu44RJPDqg==" }, "node_modules/@typescript-eslint/eslint-plugin": { - "version": "6.19.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-6.19.1.tgz", - "integrity": "sha512-roQScUGFruWod9CEyoV5KlCYrubC/fvG8/1zXuT0WTcxX87GnMMmnksMwSg99lo1xiKrBzw2icsJPMAw1OtKxg==", + "version": "6.20.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-6.20.0.tgz", + "integrity": "sha512-fTwGQUnjhoYHeSF6m5pWNkzmDDdsKELYrOBxhjMrofPqCkoC2k3B2wvGHFxa1CTIqkEn88nlW1HVMztjo2K8Hg==", "dev": true, "dependencies": { "@eslint-community/regexpp": "^4.5.1", - "@typescript-eslint/scope-manager": "6.19.1", - "@typescript-eslint/type-utils": "6.19.1", - "@typescript-eslint/utils": "6.19.1", - "@typescript-eslint/visitor-keys": "6.19.1", + "@typescript-eslint/scope-manager": "6.20.0", + "@typescript-eslint/type-utils": "6.20.0", + "@typescript-eslint/utils": "6.20.0", + "@typescript-eslint/visitor-keys": "6.20.0", "debug": "^4.3.4", "graphemer": "^1.4.0", "ignore": "^5.2.4", @@ -1863,9 +1863,9 @@ } }, "node_modules/@typescript-eslint/eslint-plugin/node_modules/semver": { - "version": "7.5.4", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz", - "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==", + "version": "7.6.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.0.tgz", + "integrity": "sha512-EnwXhrlwXMk9gKu5/flx5sv/an57AkRplG3hTK68W7FRDN+k+OWBj65M7719OkA82XLBxrcX0KSHj+X5COhOVg==", "dev": true, "dependencies": { "lru-cache": "^6.0.0" @@ -1884,15 +1884,15 @@ "dev": true }, "node_modules/@typescript-eslint/parser": { - "version": "6.19.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-6.19.1.tgz", - "integrity": "sha512-WEfX22ziAh6pRE9jnbkkLGp/4RhTpffr2ZK5bJ18M8mIfA8A+k97U9ZyaXCEJRlmMHh7R9MJZWXp/r73DzINVQ==", + "version": "6.20.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-6.20.0.tgz", + "integrity": "sha512-bYerPDF/H5v6V76MdMYhjwmwgMA+jlPVqjSDq2cRqMi8bP5sR3Z+RLOiOMad3nsnmDVmn2gAFCyNgh/dIrfP/w==", "dev": true, "dependencies": { - "@typescript-eslint/scope-manager": "6.19.1", - "@typescript-eslint/types": "6.19.1", - "@typescript-eslint/typescript-estree": "6.19.1", - "@typescript-eslint/visitor-keys": "6.19.1", + "@typescript-eslint/scope-manager": "6.20.0", + "@typescript-eslint/types": "6.20.0", + "@typescript-eslint/typescript-estree": "6.20.0", + "@typescript-eslint/visitor-keys": "6.20.0", "debug": "^4.3.4" }, "engines": { @@ -1912,13 +1912,13 @@ } }, "node_modules/@typescript-eslint/scope-manager": { - "version": "6.19.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-6.19.1.tgz", - "integrity": "sha512-4CdXYjKf6/6aKNMSly/BP4iCSOpvMmqtDzRtqFyyAae3z5kkqEjKndR5vDHL8rSuMIIWP8u4Mw4VxLyxZW6D5w==", + "version": "6.20.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-6.20.0.tgz", + "integrity": "sha512-p4rvHQRDTI1tGGMDFQm+GtxP1ZHyAh64WANVoyEcNMpaTFn3ox/3CcgtIlELnRfKzSs/DwYlDccJEtr3O6qBvA==", "dev": true, "dependencies": { - "@typescript-eslint/types": "6.19.1", - "@typescript-eslint/visitor-keys": "6.19.1" + "@typescript-eslint/types": "6.20.0", + "@typescript-eslint/visitor-keys": "6.20.0" }, "engines": { "node": "^16.0.0 || >=18.0.0" @@ -1929,13 +1929,13 @@ } }, "node_modules/@typescript-eslint/type-utils": { - "version": "6.19.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-6.19.1.tgz", - "integrity": "sha512-0vdyld3ecfxJuddDjACUvlAeYNrHP/pDeQk2pWBR2ESeEzQhg52DF53AbI9QCBkYE23lgkhLCZNkHn2hEXXYIg==", + "version": "6.20.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-6.20.0.tgz", + "integrity": "sha512-qnSobiJQb1F5JjN0YDRPHruQTrX7ICsmltXhkV536mp4idGAYrIyr47zF/JmkJtEcAVnIz4gUYJ7gOZa6SmN4g==", "dev": true, "dependencies": { - "@typescript-eslint/typescript-estree": "6.19.1", - "@typescript-eslint/utils": "6.19.1", + "@typescript-eslint/typescript-estree": "6.20.0", + "@typescript-eslint/utils": "6.20.0", "debug": "^4.3.4", "ts-api-utils": "^1.0.1" }, @@ -1956,9 +1956,9 @@ } }, "node_modules/@typescript-eslint/types": { - "version": "6.19.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-6.19.1.tgz", - "integrity": "sha512-6+bk6FEtBhvfYvpHsDgAL3uo4BfvnTnoge5LrrCj2eJN8g3IJdLTD4B/jK3Q6vo4Ql/Hoip9I8aB6fF+6RfDqg==", + "version": "6.20.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-6.20.0.tgz", + "integrity": "sha512-MM9mfZMAhiN4cOEcUOEx+0HmuaW3WBfukBZPCfwSqFnQy0grXYtngKCqpQN339X3RrwtzspWJrpbrupKYUSBXQ==", "dev": true, "engines": { "node": "^16.0.0 || >=18.0.0" @@ -1969,13 +1969,13 @@ } }, "node_modules/@typescript-eslint/typescript-estree": { - "version": "6.19.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-6.19.1.tgz", - "integrity": "sha512-aFdAxuhzBFRWhy+H20nYu19+Km+gFfwNO4TEqyszkMcgBDYQjmPJ61erHxuT2ESJXhlhrO7I5EFIlZ+qGR8oVA==", + "version": "6.20.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-6.20.0.tgz", + "integrity": "sha512-RnRya9q5m6YYSpBN7IzKu9FmLcYtErkDkc8/dKv81I9QiLLtVBHrjz+Ev/crAqgMNW2FCsoZF4g2QUylMnJz+g==", "dev": true, "dependencies": { - "@typescript-eslint/types": "6.19.1", - "@typescript-eslint/visitor-keys": "6.19.1", + "@typescript-eslint/types": "6.20.0", + "@typescript-eslint/visitor-keys": "6.20.0", "debug": "^4.3.4", "globby": "^11.1.0", "is-glob": "^4.0.3", @@ -2033,9 +2033,9 @@ } }, "node_modules/@typescript-eslint/typescript-estree/node_modules/semver": { - "version": "7.5.4", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz", - "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==", + "version": "7.6.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.0.tgz", + "integrity": "sha512-EnwXhrlwXMk9gKu5/flx5sv/an57AkRplG3hTK68W7FRDN+k+OWBj65M7719OkA82XLBxrcX0KSHj+X5COhOVg==", "dev": true, "dependencies": { "lru-cache": "^6.0.0" @@ -2054,17 +2054,17 @@ "dev": true }, "node_modules/@typescript-eslint/utils": { - "version": "6.19.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-6.19.1.tgz", - "integrity": "sha512-JvjfEZuP5WoMqwh9SPAPDSHSg9FBHHGhjPugSRxu5jMfjvBpq5/sGTD+9M9aQ5sh6iJ8AY/Kk/oUYVEMAPwi7w==", + "version": "6.20.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-6.20.0.tgz", + "integrity": "sha512-/EKuw+kRu2vAqCoDwDCBtDRU6CTKbUmwwI7SH7AashZ+W+7o8eiyy6V2cdOqN49KsTcASWsC5QeghYuRDTyOOg==", "dev": true, "dependencies": { "@eslint-community/eslint-utils": "^4.4.0", "@types/json-schema": "^7.0.12", "@types/semver": "^7.5.0", - "@typescript-eslint/scope-manager": "6.19.1", - "@typescript-eslint/types": "6.19.1", - "@typescript-eslint/typescript-estree": "6.19.1", + "@typescript-eslint/scope-manager": "6.20.0", + "@typescript-eslint/types": "6.20.0", + "@typescript-eslint/typescript-estree": "6.20.0", "semver": "^7.5.4" }, "engines": { @@ -2091,9 +2091,9 @@ } }, "node_modules/@typescript-eslint/utils/node_modules/semver": { - "version": "7.5.4", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz", - "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==", + "version": "7.6.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.0.tgz", + "integrity": "sha512-EnwXhrlwXMk9gKu5/flx5sv/an57AkRplG3hTK68W7FRDN+k+OWBj65M7719OkA82XLBxrcX0KSHj+X5COhOVg==", "dev": true, "dependencies": { "lru-cache": "^6.0.0" @@ -2112,12 +2112,12 @@ "dev": true }, "node_modules/@typescript-eslint/visitor-keys": { - "version": "6.19.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-6.19.1.tgz", - "integrity": "sha512-gkdtIO+xSO/SmI0W68DBg4u1KElmIUo3vXzgHyGPs6cxgB0sa3TlptRAAE0hUY1hM6FcDKEv7aIwiTGm76cXfQ==", + "version": "6.20.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-6.20.0.tgz", + "integrity": "sha512-E8Cp98kRe4gKHjJD4NExXKz/zOJ1A2hhZc+IMVD6i7w4yjIvh6VyuRI0gRtxAsXtoC35uGMaQ9rjI2zJaXDEAw==", "dev": true, "dependencies": { - "@typescript-eslint/types": "6.19.1", + "@typescript-eslint/types": "6.20.0", "eslint-visitor-keys": "^3.4.1" }, "engines": { @@ -2168,9 +2168,9 @@ } }, "node_modules/@vitest/coverage-v8": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/@vitest/coverage-v8/-/coverage-v8-1.2.1.tgz", - "integrity": "sha512-fJEhKaDwGMZtJUX7BRcGxooGwg1Hl0qt53mVup/ZJeznhvL5EodteVnb/mcByhEcvVWbK83ZF31c7nPEDi4LOQ==", + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/@vitest/coverage-v8/-/coverage-v8-1.2.2.tgz", + "integrity": "sha512-IHyKnDz18SFclIEEAHb9Y4Uxx0sPKC2VO1kdDCs1BF6Ip4S8rQprs971zIsooLUn7Afs71GRxWMWpkCGZpRMhw==", "dev": true, "dependencies": { "@ampproject/remapping": "^2.2.1", @@ -2195,13 +2195,13 @@ } }, "node_modules/@vitest/expect": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/@vitest/expect/-/expect-1.2.1.tgz", - "integrity": "sha512-/bqGXcHfyKgFWYwIgFr1QYDaR9e64pRKxgBNWNXPefPFRhgm+K3+a/dS0cUGEreWngets3dlr8w8SBRw2fCfFQ==", + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/@vitest/expect/-/expect-1.2.2.tgz", + "integrity": "sha512-3jpcdPAD7LwHUUiT2pZTj2U82I2Tcgg2oVPvKxhn6mDI2On6tfvPQTjAI4628GUGDZrCm4Zna9iQHm5cEexOAg==", "dev": true, "dependencies": { - "@vitest/spy": "1.2.1", - "@vitest/utils": "1.2.1", + "@vitest/spy": "1.2.2", + "@vitest/utils": "1.2.2", "chai": "^4.3.10" }, "funding": { @@ -2209,12 +2209,12 @@ } }, "node_modules/@vitest/runner": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/@vitest/runner/-/runner-1.2.1.tgz", - "integrity": "sha512-zc2dP5LQpzNzbpaBt7OeYAvmIsRS1KpZQw4G3WM/yqSV1cQKNKwLGmnm79GyZZjMhQGlRcSFMImLjZaUQvNVZQ==", + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/@vitest/runner/-/runner-1.2.2.tgz", + "integrity": "sha512-JctG7QZ4LSDXr5CsUweFgcpEvrcxOV1Gft7uHrvkQ+fsAVylmWQvnaAr/HDp3LAH1fztGMQZugIheTWjaGzYIg==", "dev": true, "dependencies": { - "@vitest/utils": "1.2.1", + "@vitest/utils": "1.2.2", "p-limit": "^5.0.0", "pathe": "^1.1.1" }, @@ -2250,9 +2250,9 @@ } }, "node_modules/@vitest/snapshot": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/@vitest/snapshot/-/snapshot-1.2.1.tgz", - "integrity": "sha512-Tmp/IcYEemKaqAYCS08sh0vORLJkMr0NRV76Gl8sHGxXT5151cITJCET20063wk0Yr/1koQ6dnmP6eEqezmd/Q==", + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/@vitest/snapshot/-/snapshot-1.2.2.tgz", + "integrity": "sha512-SmGY4saEw1+bwE1th6S/cZmPxz/Q4JWsl7LvbQIky2tKE35US4gd0Mjzqfr84/4OD0tikGWaWdMja/nWL5NIPA==", "dev": true, "dependencies": { "magic-string": "^0.30.5", @@ -2296,9 +2296,9 @@ "dev": true }, "node_modules/@vitest/spy": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/@vitest/spy/-/spy-1.2.1.tgz", - "integrity": "sha512-vG3a/b7INKH7L49Lbp0IWrG6sw9j4waWAucwnksPB1r1FTJgV7nkBByd9ufzu6VWya/QTvQW4V9FShZbZIB2UQ==", + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/@vitest/spy/-/spy-1.2.2.tgz", + "integrity": "sha512-k9Gcahssw8d7X3pSLq3e3XEu/0L78mUkCjivUqCQeXJm9clfXR/Td8+AP+VC1O6fKPIDLcHDTAmBOINVuv6+7g==", "dev": true, "dependencies": { "tinyspy": "^2.2.0" @@ -2308,9 +2308,9 @@ } }, "node_modules/@vitest/utils": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/@vitest/utils/-/utils-1.2.1.tgz", - "integrity": "sha512-bsH6WVZYe/J2v3+81M5LDU8kW76xWObKIURpPrOXm2pjBniBu2MERI/XP60GpS4PHU3jyK50LUutOwrx4CyHUg==", + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/@vitest/utils/-/utils-1.2.2.tgz", + "integrity": "sha512-WKITBHLsBHlpjnDQahr+XK6RE7MiAsgrIkr0pGhQ9ygoxBfUeG0lUG5iLlzqjmKSlBv3+j5EGsriBzh+C3Tq9g==", "dev": true, "dependencies": { "diff-sequences": "^29.6.3", @@ -7370,9 +7370,9 @@ } }, "node_modules/svelte-maplibre": { - "version": "0.7.6", - "resolved": "https://registry.npmjs.org/svelte-maplibre/-/svelte-maplibre-0.7.6.tgz", - "integrity": "sha512-ntJaEz58Pas4CrCsr/YQ+0DJXoRkJTQj+oc6BckEwGrzBM9lcsJgKyMzQlNFwuMboIUBaou+aeiJOyqCSv4oFg==", + "version": "0.7.7", + "resolved": "https://registry.npmjs.org/svelte-maplibre/-/svelte-maplibre-0.7.7.tgz", + "integrity": "sha512-fnv8L3tA4EMePp9BGKAc8AvXCsg34z56NBMGjYkz6qkl90qSTY4vUhIu1KXbwjGfQmHBmPkIl9VSdnnHCMnaRA==", "dependencies": { "d3-geo": "^3.1.0", "just-compare": "^2.3.0", @@ -7622,9 +7622,9 @@ "dev": true }, "node_modules/tinypool": { - "version": "0.8.1", - "resolved": "https://registry.npmjs.org/tinypool/-/tinypool-0.8.1.tgz", - "integrity": "sha512-zBTCK0cCgRROxvs9c0CGK838sPkeokNGdQVUUwHAbynHFlmyJYj825f/oRs528HaIJ97lo0pLIlDUzwN+IorWg==", + "version": "0.8.2", + "resolved": "https://registry.npmjs.org/tinypool/-/tinypool-0.8.2.tgz", + "integrity": "sha512-SUszKYe5wgsxnNOVlBYO6IC+8VGWdVGZWAqUxp3UErNBtptZvWbwyUOyzNL59zigz2rCA92QiL3wvG+JDSdJdQ==", "dev": true, "engines": { "node": ">=14.0.0" @@ -7968,9 +7968,9 @@ } }, "node_modules/vite-node": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/vite-node/-/vite-node-1.2.1.tgz", - "integrity": "sha512-fNzHmQUSOY+y30naohBvSW7pPn/xn3Ib/uqm+5wAJQJiqQsU0NBR78XdRJb04l4bOFKjpTWld0XAfkKlrDbySg==", + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/vite-node/-/vite-node-1.2.2.tgz", + "integrity": "sha512-1as4rDTgVWJO3n1uHmUYqq7nsFgINQ9u+mRcXpjeOMJUmviqNKjcZB7UfRZrlM7MjYXMKpuWp5oGkjaFLnjawg==", "dev": true, "dependencies": { "cac": "^6.7.14", @@ -8004,16 +8004,16 @@ } }, "node_modules/vitest": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/vitest/-/vitest-1.2.1.tgz", - "integrity": "sha512-TRph8N8rnSDa5M2wKWJCMnztCZS9cDcgVTQ6tsTFTG/odHJ4l5yNVqvbeDJYJRZ6is3uxaEpFs8LL6QM+YFSdA==", + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/vitest/-/vitest-1.2.2.tgz", + "integrity": "sha512-d5Ouvrnms3GD9USIK36KG8OZ5bEvKEkITFtnGv56HFaSlbItJuYr7hv2Lkn903+AvRAgSixiamozUVfORUekjw==", "dev": true, "dependencies": { - "@vitest/expect": "1.2.1", - "@vitest/runner": "1.2.1", - "@vitest/snapshot": "1.2.1", - "@vitest/spy": "1.2.1", - "@vitest/utils": "1.2.1", + "@vitest/expect": "1.2.2", + "@vitest/runner": "1.2.2", + "@vitest/snapshot": "1.2.2", + "@vitest/spy": "1.2.2", + "@vitest/utils": "1.2.2", "acorn-walk": "^8.3.2", "cac": "^6.7.14", "chai": "^4.3.10", @@ -8026,9 +8026,9 @@ "std-env": "^3.5.0", "strip-literal": "^1.3.0", "tinybench": "^2.5.1", - "tinypool": "^0.8.1", + "tinypool": "^0.8.2", "vite": "^5.0.0", - "vite-node": "1.2.1", + "vite-node": "1.2.2", "why-is-node-running": "^2.2.2" }, "bin": { From d88ca5fb2ab989ef3b62cd4c50422131770a5ec7 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 6 Feb 2024 22:06:02 +0000 Subject: [PATCH 028/104] chore(deps): update server (#6930) * chore(deps): update server * chore: generate sql --------- Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> Co-authored-by: Daniel Dietzler --- server/package-lock.json | 274 +++++++++--------- server/package.json | 2 +- server/src/infra/sql/access.repository.sql | 56 ++-- server/src/infra/sql/album.repository.sql | 80 +++-- server/src/infra/sql/api.key.repository.sql | 8 +- server/src/infra/sql/asset.repository.sql | 48 +-- server/src/infra/sql/library.repository.sql | 22 +- server/src/infra/sql/move.repository.sql | 4 +- server/src/infra/sql/person.repository.sql | 24 +- .../src/infra/sql/shared.link.repository.sql | 8 +- server/src/infra/sql/user.repository.sql | 8 +- .../src/infra/sql/user.token.repository.sql | 2 +- 12 files changed, 311 insertions(+), 225 deletions(-) diff --git a/server/package-lock.json b/server/package-lock.json index a1c3969f88..3c94f10a07 100644 --- a/server/package-lock.json +++ b/server/package-lock.json @@ -68,7 +68,7 @@ "@types/express": "^4.17.17", "@types/fluent-ffmpeg": "^2.1.21", "@types/imagemin": "^8.0.1", - "@types/jest": "29.5.11", + "@types/jest": "29.5.12", "@types/jest-when": "^3.5.2", "@types/lodash": "^4.14.197", "@types/mock-fs": "^4.13.1", @@ -2779,9 +2779,9 @@ } }, "node_modules/@sideway/address": { - "version": "4.1.4", - "resolved": "https://registry.npmjs.org/@sideway/address/-/address-4.1.4.tgz", - "integrity": "sha512-7vwq+rOHVWjyXxVlR76Agnvhy8I9rpzjosTESvmhNeXOXdZZB15Fl+TI9x1SiHZH5Jv2wTGduSxFDIaq0m3DUw==", + "version": "4.1.5", + "resolved": "https://registry.npmjs.org/@sideway/address/-/address-4.1.5.tgz", + "integrity": "sha512-IqO/DUQHUkPeixNQ8n0JA6102hT9CmaljNTPmQ1u8MEhBo/R4Q8eKLN/vGZxuebwOroDB4cbpjheD4+/sKFK4Q==", "dependencies": { "@hapi/hoek": "^9.0.0" } @@ -3161,9 +3161,9 @@ } }, "node_modules/@types/jest": { - "version": "29.5.11", - "resolved": "https://registry.npmjs.org/@types/jest/-/jest-29.5.11.tgz", - "integrity": "sha512-S2mHmYIVe13vrm6q4kN6fLYYAka15ALQki/vgDC3mIukEOx8WJlv0kQPM+d4w8Gp6u0uSdKND04IlTXBv0rwnQ==", + "version": "29.5.12", + "resolved": "https://registry.npmjs.org/@types/jest/-/jest-29.5.12.tgz", + "integrity": "sha512-eDC8bTvT/QhYdxJAulQikueigY5AsdBRH2yDKW3yveW7svY3+DzN84/2NUgkw10RTiJbWqZrTtoGVdYlvFJdLw==", "dev": true, "dependencies": { "expect": "^29.0.0", @@ -3227,9 +3227,9 @@ } }, "node_modules/@types/node": { - "version": "20.11.6", - "resolved": "https://registry.npmjs.org/@types/node/-/node-20.11.6.tgz", - "integrity": "sha512-+EOokTnksGVgip2PbYbr3xnR7kZigh4LbybAfBAw5BpnQ+FqBYUsvCEjYd70IXKlbohQ64mzEYmMtlWUY8q//Q==", + "version": "20.11.16", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.11.16.tgz", + "integrity": "sha512-gKb0enTmRCzXSSUJDq6/sPcqrfCv2mkkG6Jt/clpn5eiCbKTY+SgZUxo+p8ZKMof5dCp9vHQUAB7wOUTod22wQ==", "dependencies": { "undici-types": "~5.26.4" } @@ -3446,16 +3446,16 @@ "dev": true }, "node_modules/@typescript-eslint/eslint-plugin": { - "version": "6.19.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-6.19.1.tgz", - "integrity": "sha512-roQScUGFruWod9CEyoV5KlCYrubC/fvG8/1zXuT0WTcxX87GnMMmnksMwSg99lo1xiKrBzw2icsJPMAw1OtKxg==", + "version": "6.20.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-6.20.0.tgz", + "integrity": "sha512-fTwGQUnjhoYHeSF6m5pWNkzmDDdsKELYrOBxhjMrofPqCkoC2k3B2wvGHFxa1CTIqkEn88nlW1HVMztjo2K8Hg==", "dev": true, "dependencies": { "@eslint-community/regexpp": "^4.5.1", - "@typescript-eslint/scope-manager": "6.19.1", - "@typescript-eslint/type-utils": "6.19.1", - "@typescript-eslint/utils": "6.19.1", - "@typescript-eslint/visitor-keys": "6.19.1", + "@typescript-eslint/scope-manager": "6.20.0", + "@typescript-eslint/type-utils": "6.20.0", + "@typescript-eslint/utils": "6.20.0", + "@typescript-eslint/visitor-keys": "6.20.0", "debug": "^4.3.4", "graphemer": "^1.4.0", "ignore": "^5.2.4", @@ -3481,15 +3481,15 @@ } }, "node_modules/@typescript-eslint/parser": { - "version": "6.19.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-6.19.1.tgz", - "integrity": "sha512-WEfX22ziAh6pRE9jnbkkLGp/4RhTpffr2ZK5bJ18M8mIfA8A+k97U9ZyaXCEJRlmMHh7R9MJZWXp/r73DzINVQ==", + "version": "6.20.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-6.20.0.tgz", + "integrity": "sha512-bYerPDF/H5v6V76MdMYhjwmwgMA+jlPVqjSDq2cRqMi8bP5sR3Z+RLOiOMad3nsnmDVmn2gAFCyNgh/dIrfP/w==", "dev": true, "dependencies": { - "@typescript-eslint/scope-manager": "6.19.1", - "@typescript-eslint/types": "6.19.1", - "@typescript-eslint/typescript-estree": "6.19.1", - "@typescript-eslint/visitor-keys": "6.19.1", + "@typescript-eslint/scope-manager": "6.20.0", + "@typescript-eslint/types": "6.20.0", + "@typescript-eslint/typescript-estree": "6.20.0", + "@typescript-eslint/visitor-keys": "6.20.0", "debug": "^4.3.4" }, "engines": { @@ -3509,13 +3509,13 @@ } }, "node_modules/@typescript-eslint/scope-manager": { - "version": "6.19.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-6.19.1.tgz", - "integrity": "sha512-4CdXYjKf6/6aKNMSly/BP4iCSOpvMmqtDzRtqFyyAae3z5kkqEjKndR5vDHL8rSuMIIWP8u4Mw4VxLyxZW6D5w==", + "version": "6.20.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-6.20.0.tgz", + "integrity": "sha512-p4rvHQRDTI1tGGMDFQm+GtxP1ZHyAh64WANVoyEcNMpaTFn3ox/3CcgtIlELnRfKzSs/DwYlDccJEtr3O6qBvA==", "dev": true, "dependencies": { - "@typescript-eslint/types": "6.19.1", - "@typescript-eslint/visitor-keys": "6.19.1" + "@typescript-eslint/types": "6.20.0", + "@typescript-eslint/visitor-keys": "6.20.0" }, "engines": { "node": "^16.0.0 || >=18.0.0" @@ -3526,13 +3526,13 @@ } }, "node_modules/@typescript-eslint/type-utils": { - "version": "6.19.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-6.19.1.tgz", - "integrity": "sha512-0vdyld3ecfxJuddDjACUvlAeYNrHP/pDeQk2pWBR2ESeEzQhg52DF53AbI9QCBkYE23lgkhLCZNkHn2hEXXYIg==", + "version": "6.20.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-6.20.0.tgz", + "integrity": "sha512-qnSobiJQb1F5JjN0YDRPHruQTrX7ICsmltXhkV536mp4idGAYrIyr47zF/JmkJtEcAVnIz4gUYJ7gOZa6SmN4g==", "dev": true, "dependencies": { - "@typescript-eslint/typescript-estree": "6.19.1", - "@typescript-eslint/utils": "6.19.1", + "@typescript-eslint/typescript-estree": "6.20.0", + "@typescript-eslint/utils": "6.20.0", "debug": "^4.3.4", "ts-api-utils": "^1.0.1" }, @@ -3553,9 +3553,9 @@ } }, "node_modules/@typescript-eslint/types": { - "version": "6.19.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-6.19.1.tgz", - "integrity": "sha512-6+bk6FEtBhvfYvpHsDgAL3uo4BfvnTnoge5LrrCj2eJN8g3IJdLTD4B/jK3Q6vo4Ql/Hoip9I8aB6fF+6RfDqg==", + "version": "6.20.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-6.20.0.tgz", + "integrity": "sha512-MM9mfZMAhiN4cOEcUOEx+0HmuaW3WBfukBZPCfwSqFnQy0grXYtngKCqpQN339X3RrwtzspWJrpbrupKYUSBXQ==", "dev": true, "engines": { "node": "^16.0.0 || >=18.0.0" @@ -3566,13 +3566,13 @@ } }, "node_modules/@typescript-eslint/typescript-estree": { - "version": "6.19.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-6.19.1.tgz", - "integrity": "sha512-aFdAxuhzBFRWhy+H20nYu19+Km+gFfwNO4TEqyszkMcgBDYQjmPJ61erHxuT2ESJXhlhrO7I5EFIlZ+qGR8oVA==", + "version": "6.20.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-6.20.0.tgz", + "integrity": "sha512-RnRya9q5m6YYSpBN7IzKu9FmLcYtErkDkc8/dKv81I9QiLLtVBHrjz+Ev/crAqgMNW2FCsoZF4g2QUylMnJz+g==", "dev": true, "dependencies": { - "@typescript-eslint/types": "6.19.1", - "@typescript-eslint/visitor-keys": "6.19.1", + "@typescript-eslint/types": "6.20.0", + "@typescript-eslint/visitor-keys": "6.20.0", "debug": "^4.3.4", "globby": "^11.1.0", "is-glob": "^4.0.3", @@ -3618,17 +3618,17 @@ } }, "node_modules/@typescript-eslint/utils": { - "version": "6.19.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-6.19.1.tgz", - "integrity": "sha512-JvjfEZuP5WoMqwh9SPAPDSHSg9FBHHGhjPugSRxu5jMfjvBpq5/sGTD+9M9aQ5sh6iJ8AY/Kk/oUYVEMAPwi7w==", + "version": "6.20.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-6.20.0.tgz", + "integrity": "sha512-/EKuw+kRu2vAqCoDwDCBtDRU6CTKbUmwwI7SH7AashZ+W+7o8eiyy6V2cdOqN49KsTcASWsC5QeghYuRDTyOOg==", "dev": true, "dependencies": { "@eslint-community/eslint-utils": "^4.4.0", "@types/json-schema": "^7.0.12", "@types/semver": "^7.5.0", - "@typescript-eslint/scope-manager": "6.19.1", - "@typescript-eslint/types": "6.19.1", - "@typescript-eslint/typescript-estree": "6.19.1", + "@typescript-eslint/scope-manager": "6.20.0", + "@typescript-eslint/types": "6.20.0", + "@typescript-eslint/typescript-estree": "6.20.0", "semver": "^7.5.4" }, "engines": { @@ -3643,12 +3643,12 @@ } }, "node_modules/@typescript-eslint/visitor-keys": { - "version": "6.19.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-6.19.1.tgz", - "integrity": "sha512-gkdtIO+xSO/SmI0W68DBg4u1KElmIUo3vXzgHyGPs6cxgB0sa3TlptRAAE0hUY1hM6FcDKEv7aIwiTGm76cXfQ==", + "version": "6.20.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-6.20.0.tgz", + "integrity": "sha512-E8Cp98kRe4gKHjJD4NExXKz/zOJ1A2hhZc+IMVD6i7w4yjIvh6VyuRI0gRtxAsXtoC35uGMaQ9rjI2zJaXDEAw==", "dev": true, "dependencies": { - "@typescript-eslint/types": "6.19.1", + "@typescript-eslint/types": "6.20.0", "eslint-visitor-keys": "^3.4.1" }, "engines": { @@ -4174,9 +4174,9 @@ "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==" }, "node_modules/axios": { - "version": "1.6.6", - "resolved": "https://registry.npmjs.org/axios/-/axios-1.6.6.tgz", - "integrity": "sha512-XZLZDFfXKM9U/Y/B4nNynfCRUqNyVZ4sBC/n9GDRCkq9vd2mIvKjKKsbIh1WPmHmNbg6ND7cTBY3Y2+u1G3/2Q==", + "version": "1.6.7", + "resolved": "https://registry.npmjs.org/axios/-/axios-1.6.7.tgz", + "integrity": "sha512-/hDJGff6/c7u0hDkvkGxR/oy6CbCs8ziCsC7SqmhjfozqiJGc8Z11wrv9z9lYfY4K8l+H9TpjcMDX0xOZmx+RA==", "dependencies": { "follow-redirects": "^1.15.4", "form-data": "^4.0.0", @@ -8163,13 +8163,13 @@ } }, "node_modules/joi": { - "version": "17.12.0", - "resolved": "https://registry.npmjs.org/joi/-/joi-17.12.0.tgz", - "integrity": "sha512-HSLsmSmXz+PV9PYoi3p7cgIbj06WnEBNT28n+bbBNcPZXZFqCzzvGqpTBPujx/Z0nh1+KNQPDrNgdmQ8dq0qYw==", + "version": "17.12.1", + "resolved": "https://registry.npmjs.org/joi/-/joi-17.12.1.tgz", + "integrity": "sha512-vtxmq+Lsc5SlfqotnfVjlViWfOL9nt/avKNbKYizwf6gsCfq9NYY/ceYRMFD8XDdrjJ9abJyScWmhmIiy+XRtQ==", "dependencies": { "@hapi/hoek": "^9.3.0", "@hapi/topo": "^5.1.0", - "@sideway/address": "^4.1.4", + "@sideway/address": "^4.1.5", "@sideway/formula": "^3.0.1", "@sideway/pinpoint": "^2.0.0" } @@ -10823,9 +10823,9 @@ "dev": true }, "node_modules/sql-formatter": { - "version": "15.1.2", - "resolved": "https://registry.npmjs.org/sql-formatter/-/sql-formatter-15.1.2.tgz", - "integrity": "sha512-zBrLBclCNurCsQaO6yMvkXzHvv7eJPjiF8LIEQ5HdBV/x6UuWIZwqss3mlZ/6HLj+VYhFKeHpQnyLuZWG2agKQ==", + "version": "15.2.0", + "resolved": "https://registry.npmjs.org/sql-formatter/-/sql-formatter-15.2.0.tgz", + "integrity": "sha512-k1gDOblvmtzmrBT687Y167ElwQI/8KrlhfKeIUXsi6jw7Rp5n3G8TkMFZF0Z9NG7rAzHKXUlJ8kfmcIfMf5lFg==", "dev": true, "dependencies": { "argparse": "^2.0.1", @@ -11872,9 +11872,9 @@ "integrity": "sha512-/aCDEGatGvZ2BIk+HmLf4ifCJFwvKFNb9/JeZPMulfgFracn9QFcAf5GO8B/mweUjSoblS5In0cWhqpfs/5PQA==" }, "node_modules/typeorm": { - "version": "0.3.19", - "resolved": "https://registry.npmjs.org/typeorm/-/typeorm-0.3.19.tgz", - "integrity": "sha512-OGelrY5qEoAU80mR1iyvmUHiKCPUydL6xp6bebXzS7jyv/X70Gp/jBWRAfF4qGOfy2A7orMiGRfwsBUNbEL65g==", + "version": "0.3.20", + "resolved": "https://registry.npmjs.org/typeorm/-/typeorm-0.3.20.tgz", + "integrity": "sha512-sJ0T08dV5eoZroaq9uPKBoNcGslHBR4E4y+EBHs//SiGbblGe7IeduP/IH4ddCcj0qp3PHwDwGnuvqEAnKlq/Q==", "dependencies": { "@sqltools/formatter": "^1.2.5", "app-root-path": "^3.1.0", @@ -11886,7 +11886,7 @@ "dotenv": "^16.0.3", "glob": "^10.3.10", "mkdirp": "^2.1.3", - "reflect-metadata": "^0.1.13", + "reflect-metadata": "^0.2.1", "sha.js": "^2.4.11", "tslib": "^2.5.0", "uuid": "^9.0.0", @@ -11898,7 +11898,7 @@ "typeorm-ts-node-esm": "cli-ts-node-esm.js" }, "engines": { - "node": ">= 12.9.0" + "node": ">=16.13.0" }, "funding": { "url": "https://opencollective.com/typeorm" @@ -12026,6 +12026,11 @@ "url": "https://github.com/sponsors/isaacs" } }, + "node_modules/typeorm/node_modules/reflect-metadata": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/reflect-metadata/-/reflect-metadata-0.2.1.tgz", + "integrity": "sha512-i5lLI6iw9AU3Uu4szRNPPEkomnkjRTaVt9hy/bn5g/oSzekBSMeLZblcjP74AW0vBabqERLLIrz+gR8QYR54Tw==" + }, "node_modules/typeorm/node_modules/wrap-ansi": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", @@ -14358,9 +14363,9 @@ "dev": true }, "@sideway/address": { - "version": "4.1.4", - "resolved": "https://registry.npmjs.org/@sideway/address/-/address-4.1.4.tgz", - "integrity": "sha512-7vwq+rOHVWjyXxVlR76Agnvhy8I9rpzjosTESvmhNeXOXdZZB15Fl+TI9x1SiHZH5Jv2wTGduSxFDIaq0m3DUw==", + "version": "4.1.5", + "resolved": "https://registry.npmjs.org/@sideway/address/-/address-4.1.5.tgz", + "integrity": "sha512-IqO/DUQHUkPeixNQ8n0JA6102hT9CmaljNTPmQ1u8MEhBo/R4Q8eKLN/vGZxuebwOroDB4cbpjheD4+/sKFK4Q==", "requires": { "@hapi/hoek": "^9.0.0" } @@ -14725,9 +14730,9 @@ } }, "@types/jest": { - "version": "29.5.11", - "resolved": "https://registry.npmjs.org/@types/jest/-/jest-29.5.11.tgz", - "integrity": "sha512-S2mHmYIVe13vrm6q4kN6fLYYAka15ALQki/vgDC3mIukEOx8WJlv0kQPM+d4w8Gp6u0uSdKND04IlTXBv0rwnQ==", + "version": "29.5.12", + "resolved": "https://registry.npmjs.org/@types/jest/-/jest-29.5.12.tgz", + "integrity": "sha512-eDC8bTvT/QhYdxJAulQikueigY5AsdBRH2yDKW3yveW7svY3+DzN84/2NUgkw10RTiJbWqZrTtoGVdYlvFJdLw==", "dev": true, "requires": { "expect": "^29.0.0", @@ -14791,9 +14796,9 @@ } }, "@types/node": { - "version": "20.11.6", - "resolved": "https://registry.npmjs.org/@types/node/-/node-20.11.6.tgz", - "integrity": "sha512-+EOokTnksGVgip2PbYbr3xnR7kZigh4LbybAfBAw5BpnQ+FqBYUsvCEjYd70IXKlbohQ64mzEYmMtlWUY8q//Q==", + "version": "20.11.16", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.11.16.tgz", + "integrity": "sha512-gKb0enTmRCzXSSUJDq6/sPcqrfCv2mkkG6Jt/clpn5eiCbKTY+SgZUxo+p8ZKMof5dCp9vHQUAB7wOUTod22wQ==", "requires": { "undici-types": "~5.26.4" } @@ -14997,16 +15002,16 @@ "dev": true }, "@typescript-eslint/eslint-plugin": { - "version": "6.19.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-6.19.1.tgz", - "integrity": "sha512-roQScUGFruWod9CEyoV5KlCYrubC/fvG8/1zXuT0WTcxX87GnMMmnksMwSg99lo1xiKrBzw2icsJPMAw1OtKxg==", + "version": "6.20.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-6.20.0.tgz", + "integrity": "sha512-fTwGQUnjhoYHeSF6m5pWNkzmDDdsKELYrOBxhjMrofPqCkoC2k3B2wvGHFxa1CTIqkEn88nlW1HVMztjo2K8Hg==", "dev": true, "requires": { "@eslint-community/regexpp": "^4.5.1", - "@typescript-eslint/scope-manager": "6.19.1", - "@typescript-eslint/type-utils": "6.19.1", - "@typescript-eslint/utils": "6.19.1", - "@typescript-eslint/visitor-keys": "6.19.1", + "@typescript-eslint/scope-manager": "6.20.0", + "@typescript-eslint/type-utils": "6.20.0", + "@typescript-eslint/utils": "6.20.0", + "@typescript-eslint/visitor-keys": "6.20.0", "debug": "^4.3.4", "graphemer": "^1.4.0", "ignore": "^5.2.4", @@ -15016,54 +15021,54 @@ } }, "@typescript-eslint/parser": { - "version": "6.19.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-6.19.1.tgz", - "integrity": "sha512-WEfX22ziAh6pRE9jnbkkLGp/4RhTpffr2ZK5bJ18M8mIfA8A+k97U9ZyaXCEJRlmMHh7R9MJZWXp/r73DzINVQ==", + "version": "6.20.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-6.20.0.tgz", + "integrity": "sha512-bYerPDF/H5v6V76MdMYhjwmwgMA+jlPVqjSDq2cRqMi8bP5sR3Z+RLOiOMad3nsnmDVmn2gAFCyNgh/dIrfP/w==", "dev": true, "requires": { - "@typescript-eslint/scope-manager": "6.19.1", - "@typescript-eslint/types": "6.19.1", - "@typescript-eslint/typescript-estree": "6.19.1", - "@typescript-eslint/visitor-keys": "6.19.1", + "@typescript-eslint/scope-manager": "6.20.0", + "@typescript-eslint/types": "6.20.0", + "@typescript-eslint/typescript-estree": "6.20.0", + "@typescript-eslint/visitor-keys": "6.20.0", "debug": "^4.3.4" } }, "@typescript-eslint/scope-manager": { - "version": "6.19.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-6.19.1.tgz", - "integrity": "sha512-4CdXYjKf6/6aKNMSly/BP4iCSOpvMmqtDzRtqFyyAae3z5kkqEjKndR5vDHL8rSuMIIWP8u4Mw4VxLyxZW6D5w==", + "version": "6.20.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-6.20.0.tgz", + "integrity": "sha512-p4rvHQRDTI1tGGMDFQm+GtxP1ZHyAh64WANVoyEcNMpaTFn3ox/3CcgtIlELnRfKzSs/DwYlDccJEtr3O6qBvA==", "dev": true, "requires": { - "@typescript-eslint/types": "6.19.1", - "@typescript-eslint/visitor-keys": "6.19.1" + "@typescript-eslint/types": "6.20.0", + "@typescript-eslint/visitor-keys": "6.20.0" } }, "@typescript-eslint/type-utils": { - "version": "6.19.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-6.19.1.tgz", - "integrity": "sha512-0vdyld3ecfxJuddDjACUvlAeYNrHP/pDeQk2pWBR2ESeEzQhg52DF53AbI9QCBkYE23lgkhLCZNkHn2hEXXYIg==", + "version": "6.20.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-6.20.0.tgz", + "integrity": "sha512-qnSobiJQb1F5JjN0YDRPHruQTrX7ICsmltXhkV536mp4idGAYrIyr47zF/JmkJtEcAVnIz4gUYJ7gOZa6SmN4g==", "dev": true, "requires": { - "@typescript-eslint/typescript-estree": "6.19.1", - "@typescript-eslint/utils": "6.19.1", + "@typescript-eslint/typescript-estree": "6.20.0", + "@typescript-eslint/utils": "6.20.0", "debug": "^4.3.4", "ts-api-utils": "^1.0.1" } }, "@typescript-eslint/types": { - "version": "6.19.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-6.19.1.tgz", - "integrity": "sha512-6+bk6FEtBhvfYvpHsDgAL3uo4BfvnTnoge5LrrCj2eJN8g3IJdLTD4B/jK3Q6vo4Ql/Hoip9I8aB6fF+6RfDqg==", + "version": "6.20.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-6.20.0.tgz", + "integrity": "sha512-MM9mfZMAhiN4cOEcUOEx+0HmuaW3WBfukBZPCfwSqFnQy0grXYtngKCqpQN339X3RrwtzspWJrpbrupKYUSBXQ==", "dev": true }, "@typescript-eslint/typescript-estree": { - "version": "6.19.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-6.19.1.tgz", - "integrity": "sha512-aFdAxuhzBFRWhy+H20nYu19+Km+gFfwNO4TEqyszkMcgBDYQjmPJ61erHxuT2ESJXhlhrO7I5EFIlZ+qGR8oVA==", + "version": "6.20.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-6.20.0.tgz", + "integrity": "sha512-RnRya9q5m6YYSpBN7IzKu9FmLcYtErkDkc8/dKv81I9QiLLtVBHrjz+Ev/crAqgMNW2FCsoZF4g2QUylMnJz+g==", "dev": true, "requires": { - "@typescript-eslint/types": "6.19.1", - "@typescript-eslint/visitor-keys": "6.19.1", + "@typescript-eslint/types": "6.20.0", + "@typescript-eslint/visitor-keys": "6.20.0", "debug": "^4.3.4", "globby": "^11.1.0", "is-glob": "^4.0.3", @@ -15093,27 +15098,27 @@ } }, "@typescript-eslint/utils": { - "version": "6.19.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-6.19.1.tgz", - "integrity": "sha512-JvjfEZuP5WoMqwh9SPAPDSHSg9FBHHGhjPugSRxu5jMfjvBpq5/sGTD+9M9aQ5sh6iJ8AY/Kk/oUYVEMAPwi7w==", + "version": "6.20.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-6.20.0.tgz", + "integrity": "sha512-/EKuw+kRu2vAqCoDwDCBtDRU6CTKbUmwwI7SH7AashZ+W+7o8eiyy6V2cdOqN49KsTcASWsC5QeghYuRDTyOOg==", "dev": true, "requires": { "@eslint-community/eslint-utils": "^4.4.0", "@types/json-schema": "^7.0.12", "@types/semver": "^7.5.0", - "@typescript-eslint/scope-manager": "6.19.1", - "@typescript-eslint/types": "6.19.1", - "@typescript-eslint/typescript-estree": "6.19.1", + "@typescript-eslint/scope-manager": "6.20.0", + "@typescript-eslint/types": "6.20.0", + "@typescript-eslint/typescript-estree": "6.20.0", "semver": "^7.5.4" } }, "@typescript-eslint/visitor-keys": { - "version": "6.19.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-6.19.1.tgz", - "integrity": "sha512-gkdtIO+xSO/SmI0W68DBg4u1KElmIUo3vXzgHyGPs6cxgB0sa3TlptRAAE0hUY1hM6FcDKEv7aIwiTGm76cXfQ==", + "version": "6.20.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-6.20.0.tgz", + "integrity": "sha512-E8Cp98kRe4gKHjJD4NExXKz/zOJ1A2hhZc+IMVD6i7w4yjIvh6VyuRI0gRtxAsXtoC35uGMaQ9rjI2zJaXDEAw==", "dev": true, "requires": { - "@typescript-eslint/types": "6.19.1", + "@typescript-eslint/types": "6.20.0", "eslint-visitor-keys": "^3.4.1" } }, @@ -15550,9 +15555,9 @@ "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==" }, "axios": { - "version": "1.6.6", - "resolved": "https://registry.npmjs.org/axios/-/axios-1.6.6.tgz", - "integrity": "sha512-XZLZDFfXKM9U/Y/B4nNynfCRUqNyVZ4sBC/n9GDRCkq9vd2mIvKjKKsbIh1WPmHmNbg6ND7cTBY3Y2+u1G3/2Q==", + "version": "1.6.7", + "resolved": "https://registry.npmjs.org/axios/-/axios-1.6.7.tgz", + "integrity": "sha512-/hDJGff6/c7u0hDkvkGxR/oy6CbCs8ziCsC7SqmhjfozqiJGc8Z11wrv9z9lYfY4K8l+H9TpjcMDX0xOZmx+RA==", "requires": { "follow-redirects": "^1.15.4", "form-data": "^4.0.0", @@ -18494,13 +18499,13 @@ } }, "joi": { - "version": "17.12.0", - "resolved": "https://registry.npmjs.org/joi/-/joi-17.12.0.tgz", - "integrity": "sha512-HSLsmSmXz+PV9PYoi3p7cgIbj06WnEBNT28n+bbBNcPZXZFqCzzvGqpTBPujx/Z0nh1+KNQPDrNgdmQ8dq0qYw==", + "version": "17.12.1", + "resolved": "https://registry.npmjs.org/joi/-/joi-17.12.1.tgz", + "integrity": "sha512-vtxmq+Lsc5SlfqotnfVjlViWfOL9nt/avKNbKYizwf6gsCfq9NYY/ceYRMFD8XDdrjJ9abJyScWmhmIiy+XRtQ==", "requires": { "@hapi/hoek": "^9.3.0", "@hapi/topo": "^5.1.0", - "@sideway/address": "^4.1.4", + "@sideway/address": "^4.1.5", "@sideway/formula": "^3.0.1", "@sideway/pinpoint": "^2.0.0" } @@ -20532,9 +20537,9 @@ "dev": true }, "sql-formatter": { - "version": "15.1.2", - "resolved": "https://registry.npmjs.org/sql-formatter/-/sql-formatter-15.1.2.tgz", - "integrity": "sha512-zBrLBclCNurCsQaO6yMvkXzHvv7eJPjiF8LIEQ5HdBV/x6UuWIZwqss3mlZ/6HLj+VYhFKeHpQnyLuZWG2agKQ==", + "version": "15.2.0", + "resolved": "https://registry.npmjs.org/sql-formatter/-/sql-formatter-15.2.0.tgz", + "integrity": "sha512-k1gDOblvmtzmrBT687Y167ElwQI/8KrlhfKeIUXsi6jw7Rp5n3G8TkMFZF0Z9NG7rAzHKXUlJ8kfmcIfMf5lFg==", "dev": true, "requires": { "argparse": "^2.0.1", @@ -21320,9 +21325,9 @@ "integrity": "sha512-/aCDEGatGvZ2BIk+HmLf4ifCJFwvKFNb9/JeZPMulfgFracn9QFcAf5GO8B/mweUjSoblS5In0cWhqpfs/5PQA==" }, "typeorm": { - "version": "0.3.19", - "resolved": "https://registry.npmjs.org/typeorm/-/typeorm-0.3.19.tgz", - "integrity": "sha512-OGelrY5qEoAU80mR1iyvmUHiKCPUydL6xp6bebXzS7jyv/X70Gp/jBWRAfF4qGOfy2A7orMiGRfwsBUNbEL65g==", + "version": "0.3.20", + "resolved": "https://registry.npmjs.org/typeorm/-/typeorm-0.3.20.tgz", + "integrity": "sha512-sJ0T08dV5eoZroaq9uPKBoNcGslHBR4E4y+EBHs//SiGbblGe7IeduP/IH4ddCcj0qp3PHwDwGnuvqEAnKlq/Q==", "requires": { "@sqltools/formatter": "^1.2.5", "app-root-path": "^3.1.0", @@ -21334,7 +21339,7 @@ "dotenv": "^16.0.3", "glob": "^10.3.10", "mkdirp": "^2.1.3", - "reflect-metadata": "^0.1.13", + "reflect-metadata": "^0.2.1", "sha.js": "^2.4.11", "tslib": "^2.5.0", "uuid": "^9.0.0", @@ -21365,6 +21370,11 @@ "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-2.1.6.tgz", "integrity": "sha512-+hEnITedc8LAtIP9u3HJDFIdcLV2vXP33sqLLIzkv1Db1zO/1OxbvYf0Y1OC/S/Qo5dxHXepofhmxL02PsKe+A==" }, + "reflect-metadata": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/reflect-metadata/-/reflect-metadata-0.2.1.tgz", + "integrity": "sha512-i5lLI6iw9AU3Uu4szRNPPEkomnkjRTaVt9hy/bn5g/oSzekBSMeLZblcjP74AW0vBabqERLLIrz+gR8QYR54Tw==" + }, "wrap-ansi": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", diff --git a/server/package.json b/server/package.json index 481c878481..16c2042ecf 100644 --- a/server/package.json +++ b/server/package.json @@ -93,7 +93,7 @@ "@types/express": "^4.17.17", "@types/fluent-ffmpeg": "^2.1.21", "@types/imagemin": "^8.0.1", - "@types/jest": "29.5.11", + "@types/jest": "29.5.12", "@types/jest-when": "^3.5.2", "@types/lodash": "^4.14.197", "@types/mock-fs": "^4.13.1", diff --git a/server/src/infra/sql/access.repository.sql b/server/src/infra/sql/access.repository.sql index f2ed3f9a38..638be9f90b 100644 --- a/server/src/infra/sql/access.repository.sql +++ b/server/src/infra/sql/access.repository.sql @@ -7,8 +7,8 @@ FROM "activity" "ActivityEntity" WHERE ( - "ActivityEntity"."id" IN ($1) - AND "ActivityEntity"."userId" = $2 + ("ActivityEntity"."id" IN ($1)) + AND ("ActivityEntity"."userId" = $2) ) -- AccessRepository.activity.checkAlbumOwnerAccess @@ -22,8 +22,14 @@ FROM ) WHERE ( - "ActivityEntity"."id" IN ($1) - AND "ActivityEntity__ActivityEntity_album"."ownerId" = $2 + ("ActivityEntity"."id" IN ($1)) + AND ( + ( + ( + "ActivityEntity__ActivityEntity_album"."ownerId" = $2 + ) + ) + ) ) -- AccessRepository.activity.checkCreateAccess @@ -53,8 +59,8 @@ FROM WHERE ( ( - "AlbumEntity"."id" IN ($1) - AND "AlbumEntity"."ownerId" = $2 + ("AlbumEntity"."id" IN ($1)) + AND ("AlbumEntity"."ownerId" = $2) ) ) AND ("AlbumEntity"."deletedAt" IS NULL) @@ -72,8 +78,12 @@ FROM WHERE ( ( - "AlbumEntity"."id" IN ($1) - AND "AlbumEntity__AlbumEntity_sharedUsers"."id" = $2 + ("AlbumEntity"."id" IN ($1)) + AND ( + ( + ("AlbumEntity__AlbumEntity_sharedUsers"."id" = $2) + ) + ) ) ) AND ("AlbumEntity"."deletedAt" IS NULL) @@ -86,8 +96,8 @@ FROM "shared_links" "SharedLinkEntity" WHERE ( - "SharedLinkEntity"."id" = $1 - AND "SharedLinkEntity"."albumId" IN ($2) + ("SharedLinkEntity"."id" = $1) + AND ("SharedLinkEntity"."albumId" IN ($2)) ) -- AccessRepository.asset.checkAlbumAccess @@ -119,8 +129,8 @@ FROM "assets" "AssetEntity" WHERE ( - "AssetEntity"."id" IN ($1) - AND "AssetEntity"."ownerId" = $2 + ("AssetEntity"."id" IN ($1)) + AND ("AssetEntity"."ownerId" = $2) ) -- AccessRepository.asset.checkPartnerAccess @@ -168,8 +178,8 @@ FROM "user_token" "UserTokenEntity" WHERE ( - "UserTokenEntity"."userId" = $1 - AND "UserTokenEntity"."id" IN ($2) + ("UserTokenEntity"."userId" = $1) + AND ("UserTokenEntity"."id" IN ($2)) ) -- AccessRepository.library.checkOwnerAccess @@ -180,8 +190,8 @@ FROM WHERE ( ( - "LibraryEntity"."id" IN ($1) - AND "LibraryEntity"."ownerId" = $2 + ("LibraryEntity"."id" IN ($1)) + AND ("LibraryEntity"."ownerId" = $2) ) ) AND ("LibraryEntity"."deletedAt" IS NULL) @@ -203,8 +213,8 @@ FROM "person" "PersonEntity" WHERE ( - "PersonEntity"."id" IN ($1) - AND "PersonEntity"."ownerId" = $2 + ("PersonEntity"."id" IN ($1)) + AND ("PersonEntity"."ownerId" = $2) ) -- AccessRepository.person.checkFaceOwnerAccess @@ -218,8 +228,14 @@ FROM ) WHERE ( - "AssetFaceEntity"."id" IN ($1) - AND "AssetFaceEntity__AssetFaceEntity_asset"."ownerId" = $2 + ("AssetFaceEntity"."id" IN ($1)) + AND ( + ( + ( + "AssetFaceEntity__AssetFaceEntity_asset"."ownerId" = $2 + ) + ) + ) ) -- AccessRepository.partner.checkUpdateAccess diff --git a/server/src/infra/sql/album.repository.sql b/server/src/infra/sql/album.repository.sql index a5f32f57a7..5e104bc1a2 100644 --- a/server/src/infra/sql/album.repository.sql +++ b/server/src/infra/sql/album.repository.sql @@ -72,7 +72,7 @@ FROM ) LEFT JOIN "shared_links" "AlbumEntity__AlbumEntity_sharedLinks" ON "AlbumEntity__AlbumEntity_sharedLinks"."albumId" = "AlbumEntity"."id" WHERE - (("AlbumEntity"."id" = $1)) + ((("AlbumEntity"."id" = $1))) AND ("AlbumEntity"."deletedAt" IS NULL) ) "distinctAlias" ORDER BY @@ -135,7 +135,7 @@ FROM "AlbumEntity__AlbumEntity_sharedUsers"."deletedAt" IS NULL ) WHERE - (("AlbumEntity"."id" IN ($1))) + ((("AlbumEntity"."id" IN ($1)))) AND ("AlbumEntity"."deletedAt" IS NULL) -- AlbumRepository.getByAssetId @@ -201,12 +201,20 @@ WHERE ( ( ( - "AlbumEntity"."ownerId" = $1 - AND "AlbumEntity__AlbumEntity_assets"."id" = $2 + ( + ("AlbumEntity"."ownerId" = $1) + AND ((("AlbumEntity__AlbumEntity_assets"."id" = $2))) + ) ) OR ( - "AlbumEntity__AlbumEntity_sharedUsers"."id" = $3 - AND "AlbumEntity__AlbumEntity_assets"."id" = $4 + ( + ( + ( + ("AlbumEntity__AlbumEntity_sharedUsers"."id" = $3) + ) + ) + AND ((("AlbumEntity__AlbumEntity_assets"."id" = $4))) + ) ) ) ) @@ -328,7 +336,7 @@ FROM "AlbumEntity__AlbumEntity_owner"."deletedAt" IS NULL ) WHERE - (("AlbumEntity"."ownerId" = $1)) + ((("AlbumEntity"."ownerId" = $1))) AND ("AlbumEntity"."deletedAt" IS NULL) ORDER BY "AlbumEntity"."createdAt" DESC @@ -403,14 +411,38 @@ FROM WHERE ( ( - ("AlbumEntity__AlbumEntity_sharedUsers"."id" = $1) - OR ( - "AlbumEntity__AlbumEntity_sharedLinks"."userId" = $2 + ( + ( + ( + ( + ("AlbumEntity__AlbumEntity_sharedUsers"."id" = $1) + ) + ) + ) ) OR ( - "AlbumEntity"."ownerId" = $3 - AND NOT ( - "AlbumEntity__AlbumEntity_sharedUsers"."id" IS NULL + ( + ( + ( + ( + "AlbumEntity__AlbumEntity_sharedLinks"."userId" = $2 + ) + ) + ) + ) + ) + OR ( + ( + ("AlbumEntity"."ownerId" = $3) + AND ( + ( + ( + NOT ( + "AlbumEntity__AlbumEntity_sharedUsers"."id" IS NULL + ) + ) + ) + ) ) ) ) @@ -489,9 +521,21 @@ FROM WHERE ( ( - "AlbumEntity"."ownerId" = $1 - AND "AlbumEntity__AlbumEntity_sharedUsers"."id" IS NULL - AND "AlbumEntity__AlbumEntity_sharedLinks"."id" IS NULL + ("AlbumEntity"."ownerId" = $1) + AND ( + ( + ( + "AlbumEntity__AlbumEntity_sharedUsers"."id" IS NULL + ) + ) + ) + AND ( + ( + ( + "AlbumEntity__AlbumEntity_sharedLinks"."id" IS NULL + ) + ) + ) ) ) AND ("AlbumEntity"."deletedAt" IS NULL) @@ -586,8 +630,8 @@ WHERE WHERE ( ( - "AlbumEntity"."id" = $1 - AND "AlbumEntity__AlbumEntity_assets"."id" = $2 + ("AlbumEntity"."id" = $1) + AND ((("AlbumEntity__AlbumEntity_assets"."id" = $2))) ) ) AND ("AlbumEntity"."deletedAt" IS NULL) diff --git a/server/src/infra/sql/api.key.repository.sql b/server/src/infra/sql/api.key.repository.sql index 71d8022ca5..78eab13b30 100644 --- a/server/src/infra/sql/api.key.repository.sql +++ b/server/src/infra/sql/api.key.repository.sql @@ -32,7 +32,7 @@ FROM "APIKeyEntity__APIKeyEntity_user"."deletedAt" IS NULL ) WHERE - ("APIKeyEntity"."key" = $1) + (("APIKeyEntity"."key" = $1)) ) "distinctAlias" ORDER BY "APIKeyEntity_id" ASC @@ -50,8 +50,8 @@ FROM "api_keys" "APIKeyEntity" WHERE ( - "APIKeyEntity"."userId" = $1 - AND "APIKeyEntity"."id" = $2 + ("APIKeyEntity"."userId" = $1) + AND ("APIKeyEntity"."id" = $2) ) LIMIT 1 @@ -66,6 +66,6 @@ SELECT FROM "api_keys" "APIKeyEntity" WHERE - ("APIKeyEntity"."userId" = $1) + (("APIKeyEntity"."userId" = $1)) ORDER BY "APIKeyEntity"."createdAt" DESC diff --git a/server/src/infra/sql/asset.repository.sql b/server/src/infra/sql/asset.repository.sql index a2e30c3e3e..88f17eb920 100644 --- a/server/src/infra/sql/asset.repository.sql +++ b/server/src/infra/sql/asset.repository.sql @@ -65,11 +65,11 @@ FROM WHERE ( ( - "AssetEntity"."ownerId" = $1 - AND "AssetEntity"."isVisible" = $2 - AND "AssetEntity"."isArchived" = $3 - AND NOT ("AssetEntity"."resizePath" IS NULL) - AND "AssetEntity"."fileCreatedAt" BETWEEN $4 AND $5 + ("AssetEntity"."ownerId" = $1) + AND ("AssetEntity"."isVisible" = $2) + AND ("AssetEntity"."isArchived" = $3) + AND (NOT ("AssetEntity"."resizePath" IS NULL)) + AND ("AssetEntity"."fileCreatedAt" BETWEEN $4 AND $5) ) ) AND ("AssetEntity"."deletedAt" IS NULL) @@ -286,7 +286,7 @@ FROM LEFT JOIN "asset_stack" "AssetEntity__AssetEntity_stack" ON "AssetEntity__AssetEntity_stack"."id" = "AssetEntity"."stackId" LEFT JOIN "assets" "bd93d5747511a4dad4923546c51365bf1a803774" ON "bd93d5747511a4dad4923546c51365bf1a803774"."stackId" = "AssetEntity__AssetEntity_stack"."id" WHERE - ("AssetEntity"."id" IN ($1)) + (("AssetEntity"."id" IN ($1))) -- AssetRepository.deleteAll DELETE FROM "assets" @@ -331,7 +331,13 @@ FROM "AssetEntity__AssetEntity_library"."deletedAt" IS NULL ) WHERE - (("AssetEntity__AssetEntity_library"."id" IN ($1))) + ( + ( + ( + (("AssetEntity__AssetEntity_library"."id" IN ($1))) + ) + ) + ) AND ("AssetEntity"."deletedAt" IS NULL) -- AssetRepository.getByLibraryIdAndOriginalPath @@ -378,8 +384,8 @@ FROM WHERE ( ( - "AssetEntity__AssetEntity_library"."id" = $1 - AND "AssetEntity"."originalPath" = $2 + ((("AssetEntity__AssetEntity_library"."id" = $1))) + AND ("AssetEntity"."originalPath" = $2) ) ) AND ("AssetEntity"."deletedAt" IS NULL) @@ -397,9 +403,9 @@ FROM "assets" "AssetEntity" WHERE ( - "AssetEntity"."ownerId" = $1 - AND "AssetEntity"."deviceId" = $2 - AND "AssetEntity"."isVisible" = $3 + ("AssetEntity"."ownerId" = $1) + AND ("AssetEntity"."deviceId" = $2) + AND ("AssetEntity"."isVisible" = $3) ) -- AssetRepository.getById @@ -436,7 +442,7 @@ SELECT FROM "assets" "AssetEntity" WHERE - ("AssetEntity"."id" = $1) + (("AssetEntity"."id" = $1)) LIMIT 1 @@ -484,8 +490,8 @@ FROM WHERE ( ( - "AssetEntity"."ownerId" = $1 - AND "AssetEntity"."checksum" = $2 + ("AssetEntity"."ownerId" = $1) + AND ("AssetEntity"."checksum" = $2) ) ) AND ("AssetEntity"."deletedAt" IS NULL) @@ -529,12 +535,16 @@ WHERE ( ( ( - "AssetEntity"."sidecarPath" IS NULL - AND "AssetEntity"."isVisible" = $1 + ( + ("AssetEntity"."sidecarPath" IS NULL) + AND ("AssetEntity"."isVisible" = $1) + ) ) OR ( - "AssetEntity"."sidecarPath" = $2 - AND "AssetEntity"."isVisible" = $3 + ( + ("AssetEntity"."sidecarPath" = $2) + AND ("AssetEntity"."isVisible" = $3) + ) ) ) ) diff --git a/server/src/infra/sql/library.repository.sql b/server/src/infra/sql/library.repository.sql index 8dd7828f0b..c791b2c8a5 100644 --- a/server/src/infra/sql/library.repository.sql +++ b/server/src/infra/sql/library.repository.sql @@ -40,7 +40,7 @@ FROM "LibraryEntity__LibraryEntity_owner"."deletedAt" IS NULL ) WHERE - (("LibraryEntity"."id" = $1)) + ((("LibraryEntity"."id" = $1))) AND ("LibraryEntity"."deletedAt" IS NULL) ) "distinctAlias" ORDER BY @@ -63,7 +63,7 @@ WHERE FROM "libraries" "LibraryEntity" WHERE - (("LibraryEntity"."name" = $1)) + ((("LibraryEntity"."name" = $1))) AND ("LibraryEntity"."deletedAt" IS NULL) ) LIMIT @@ -75,7 +75,7 @@ SELECT FROM "libraries" "LibraryEntity" WHERE - (("LibraryEntity"."ownerId" = $1)) + ((("LibraryEntity"."ownerId" = $1))) AND ("LibraryEntity"."deletedAt" IS NULL) -- LibraryRepository.getDefaultUploadLibrary @@ -96,8 +96,8 @@ FROM WHERE ( ( - "LibraryEntity"."ownerId" = $1 - AND "LibraryEntity"."type" = $2 + ("LibraryEntity"."ownerId" = $1) + AND ("LibraryEntity"."type" = $2) ) ) AND ("LibraryEntity"."deletedAt" IS NULL) @@ -114,8 +114,8 @@ FROM WHERE ( ( - "LibraryEntity"."ownerId" = $1 - AND "LibraryEntity"."type" = $2 + ("LibraryEntity"."ownerId" = $1) + AND ("LibraryEntity"."type" = $2) ) ) AND ("LibraryEntity"."deletedAt" IS NULL) @@ -158,8 +158,8 @@ FROM WHERE ( ( - "LibraryEntity"."ownerId" = $1 - AND "LibraryEntity"."isVisible" = $2 + ("LibraryEntity"."ownerId" = $1) + AND ("LibraryEntity"."isVisible" = $2) ) ) AND ("LibraryEntity"."deletedAt" IS NULL) @@ -240,8 +240,8 @@ FROM LEFT JOIN "users" "LibraryEntity__LibraryEntity_owner" ON "LibraryEntity__LibraryEntity_owner"."id" = "LibraryEntity"."ownerId" WHERE ( - "LibraryEntity"."isVisible" = $1 - AND NOT ("LibraryEntity"."deletedAt" IS NULL) + ("LibraryEntity"."isVisible" = $1) + AND (NOT ("LibraryEntity"."deletedAt" IS NULL)) ) ORDER BY "LibraryEntity"."createdAt" ASC diff --git a/server/src/infra/sql/move.repository.sql b/server/src/infra/sql/move.repository.sql index b83175bd3f..3ce8c0ccdd 100644 --- a/server/src/infra/sql/move.repository.sql +++ b/server/src/infra/sql/move.repository.sql @@ -11,8 +11,8 @@ FROM "move_history" "MoveEntity" WHERE ( - "MoveEntity"."entityId" = $1 - AND "MoveEntity"."pathType" = $2 + ("MoveEntity"."entityId" = $1) + AND ("MoveEntity"."pathType" = $2) ) LIMIT 1 diff --git a/server/src/infra/sql/person.repository.sql b/server/src/infra/sql/person.repository.sql index 781e68d9ae..bd4a523e86 100644 --- a/server/src/infra/sql/person.repository.sql +++ b/server/src/infra/sql/person.repository.sql @@ -83,7 +83,7 @@ FROM "asset_faces" "AssetFaceEntity" LEFT JOIN "person" "AssetFaceEntity__AssetFaceEntity_person" ON "AssetFaceEntity__AssetFaceEntity_person"."id" = "AssetFaceEntity"."personId" WHERE - ("AssetFaceEntity"."assetId" = $1) + (("AssetFaceEntity"."assetId" = $1)) -- PersonRepository.getFaceById SELECT DISTINCT @@ -113,7 +113,7 @@ FROM "asset_faces" "AssetFaceEntity" LEFT JOIN "person" "AssetFaceEntity__AssetFaceEntity_person" ON "AssetFaceEntity__AssetFaceEntity_person"."id" = "AssetFaceEntity"."personId" WHERE - ("AssetFaceEntity"."id" = $1) + (("AssetFaceEntity"."id" = $1)) ) "distinctAlias" ORDER BY "AssetFaceEntity_id" ASC @@ -181,7 +181,7 @@ FROM "AssetFaceEntity__AssetFaceEntity_asset"."deletedAt" IS NULL ) WHERE - ("AssetFaceEntity"."id" = $1) + (("AssetFaceEntity"."id" = $1)) ) "distinctAlias" ORDER BY "AssetFaceEntity_id" ASC @@ -325,9 +325,13 @@ FROM WHERE ( ( - "AssetEntity__AssetEntity_faces"."personId" = $1 - AND "AssetEntity"."isVisible" = $2 - AND "AssetEntity"."isArchived" = $3 + ( + ( + ("AssetEntity__AssetEntity_faces"."personId" = $1) + ) + ) + AND ("AssetEntity"."isVisible" = $2) + AND ("AssetEntity"."isArchived" = $3) ) ) AND ("AssetEntity"."deletedAt" IS NULL) @@ -395,8 +399,10 @@ FROM WHERE ( ( - "AssetFaceEntity"."assetId" = $1 - AND "AssetFaceEntity"."personId" = $2 + ( + ("AssetFaceEntity"."assetId" = $1) + AND ("AssetFaceEntity"."personId" = $2) + ) ) ) @@ -414,6 +420,6 @@ SELECT FROM "asset_faces" "AssetFaceEntity" WHERE - ("AssetFaceEntity"."personId" = $1) + (("AssetFaceEntity"."personId" = $1)) LIMIT 1 diff --git a/server/src/infra/sql/shared.link.repository.sql b/server/src/infra/sql/shared.link.repository.sql index ee3563b8b7..5f43210685 100644 --- a/server/src/infra/sql/shared.link.repository.sql +++ b/server/src/infra/sql/shared.link.repository.sql @@ -184,8 +184,8 @@ FROM ) WHERE ( - "SharedLinkEntity"."id" = $1 - AND "SharedLinkEntity"."userId" = $2 + ("SharedLinkEntity"."id" = $1) + AND ("SharedLinkEntity"."userId" = $2) ) ) "distinctAlias" ORDER BY @@ -280,7 +280,7 @@ FROM "6d7fd45329a05fd86b3dbcacde87fe76e33a422d"."deletedAt" IS NULL ) WHERE - ("SharedLinkEntity"."userId" = $1) + (("SharedLinkEntity"."userId" = $1)) ORDER BY "SharedLinkEntity"."createdAt" DESC @@ -325,7 +325,7 @@ FROM "SharedLinkEntity__SharedLinkEntity_user"."deletedAt" IS NULL ) WHERE - ("SharedLinkEntity"."key" = $1) + (("SharedLinkEntity"."key" = $1)) ) "distinctAlias" ORDER BY "SharedLinkEntity_id" ASC diff --git a/server/src/infra/sql/user.repository.sql b/server/src/infra/sql/user.repository.sql index 40cf14077a..29a2ee5301 100644 --- a/server/src/infra/sql/user.repository.sql +++ b/server/src/infra/sql/user.repository.sql @@ -21,7 +21,7 @@ SELECT FROM "users" "UserEntity" WHERE - (("UserEntity"."isAdmin" = $1)) + ((("UserEntity"."isAdmin" = $1))) AND ("UserEntity"."deletedAt" IS NULL) LIMIT 1 @@ -41,7 +41,7 @@ WHERE FROM "users" "UserEntity" WHERE - (("UserEntity"."isAdmin" = $1)) + ((("UserEntity"."isAdmin" = $1))) AND ("UserEntity"."deletedAt" IS NULL) ) LIMIT @@ -92,7 +92,7 @@ SELECT FROM "users" "UserEntity" WHERE - (("UserEntity"."storageLabel" = $1)) + ((("UserEntity"."storageLabel" = $1))) AND ("UserEntity"."deletedAt" IS NULL) LIMIT 1 @@ -118,7 +118,7 @@ SELECT FROM "users" "UserEntity" WHERE - (("UserEntity"."oauthId" = $1)) + ((("UserEntity"."oauthId" = $1))) AND ("UserEntity"."deletedAt" IS NULL) LIMIT 1 diff --git a/server/src/infra/sql/user.token.repository.sql b/server/src/infra/sql/user.token.repository.sql index 576dea5c4f..0f496504f5 100644 --- a/server/src/infra/sql/user.token.repository.sql +++ b/server/src/infra/sql/user.token.repository.sql @@ -35,7 +35,7 @@ FROM "UserTokenEntity__UserTokenEntity_user"."deletedAt" IS NULL ) WHERE - ("UserTokenEntity"."token" = $1) + (("UserTokenEntity"."token" = $1)) ) "distinctAlias" ORDER BY "UserTokenEntity_id" ASC From f80af067bf44f52815b2193521168e8b8b0e7ecb Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 6 Feb 2024 23:53:55 +0100 Subject: [PATCH 029/104] chore(deps): update dependency eslint-plugin-unicorn to v51 (#6952) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- cli/package-lock.json | 66 +++++++++++++++++++--------------------- cli/package.json | 2 +- server/package-lock.json | 14 ++++----- server/package.json | 2 +- web/package-lock.json | 14 ++++----- web/package.json | 2 +- 6 files changed, 49 insertions(+), 51 deletions(-) diff --git a/cli/package-lock.json b/cli/package-lock.json index ba556794cd..8324fdd9d0 100644 --- a/cli/package-lock.json +++ b/cli/package-lock.json @@ -27,7 +27,7 @@ "eslint": "^8.56.0", "eslint-config-prettier": "^9.1.0", "eslint-plugin-prettier": "^5.1.3", - "eslint-plugin-unicorn": "^50.0.1", + "eslint-plugin-unicorn": "^51.0.0", "glob": "^10.3.1", "immich": "file:../server", "mock-fs": "^5.2.0", @@ -123,7 +123,7 @@ "@types/express": "^4.17.17", "@types/fluent-ffmpeg": "^2.1.21", "@types/imagemin": "^8.0.1", - "@types/jest": "29.5.11", + "@types/jest": "29.5.12", "@types/jest-when": "^3.5.2", "@types/lodash": "^4.14.197", "@types/mock-fs": "^4.13.1", @@ -138,7 +138,7 @@ "eslint": "^8.56.0", "eslint-config-prettier": "^9.1.0", "eslint-plugin-prettier": "^5.1.3", - "eslint-plugin-unicorn": "^50.0.1", + "eslint-plugin-unicorn": "^51.0.0", "jest": "^29.6.4", "jest-when": "^3.6.0", "mock-fs": "^5.2.0", @@ -2177,6 +2177,21 @@ "integrity": "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==", "dev": true }, + "node_modules/ci-info": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-4.0.0.tgz", + "integrity": "sha512-TdHqgGf9odd8SXNuxtUBVx8Nv+qZOejE6qyqiy5NtbYYQOeFa6zmHkxlPzmaLxWWHsU6nJmB7AETdVPi+2NBUg==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/sibiraj-s" + } + ], + "engines": { + "node": ">=8" + } + }, "node_modules/clean-regexp": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/clean-regexp/-/clean-regexp-1.0.0.tgz", @@ -2651,9 +2666,9 @@ } }, "node_modules/eslint-plugin-unicorn": { - "version": "50.0.1", - "resolved": "https://registry.npmjs.org/eslint-plugin-unicorn/-/eslint-plugin-unicorn-50.0.1.tgz", - "integrity": "sha512-KxenCZxqSYW0GWHH18okDlOQcpezcitm5aOSz6EnobyJ6BIByiPDviQRjJIUAjG/tMN11958MxaQ+qCoU6lfDA==", + "version": "51.0.1", + "resolved": "https://registry.npmjs.org/eslint-plugin-unicorn/-/eslint-plugin-unicorn-51.0.1.tgz", + "integrity": "sha512-MuR/+9VuB0fydoI0nIn2RDA5WISRn4AsJyNSaNKLVwie9/ONvQhxOBbkfSICBPnzKrB77Fh6CZZXjgTt/4Latw==", "dev": true, "dependencies": { "@babel/helper-validator-identifier": "^7.22.20", @@ -2683,21 +2698,6 @@ "eslint": ">=8.56.0" } }, - "node_modules/eslint-plugin-unicorn/node_modules/ci-info": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-4.0.0.tgz", - "integrity": "sha512-TdHqgGf9odd8SXNuxtUBVx8Nv+qZOejE6qyqiy5NtbYYQOeFa6zmHkxlPzmaLxWWHsU6nJmB7AETdVPi+2NBUg==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/sibiraj-s" - } - ], - "engines": { - "node": ">=8" - } - }, "node_modules/eslint-visitor-keys": { "version": "3.4.3", "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", @@ -7036,6 +7036,12 @@ "integrity": "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==", "dev": true }, + "ci-info": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-4.0.0.tgz", + "integrity": "sha512-TdHqgGf9odd8SXNuxtUBVx8Nv+qZOejE6qyqiy5NtbYYQOeFa6zmHkxlPzmaLxWWHsU6nJmB7AETdVPi+2NBUg==", + "dev": true + }, "clean-regexp": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/clean-regexp/-/clean-regexp-1.0.0.tgz", @@ -7415,9 +7421,9 @@ } }, "eslint-plugin-unicorn": { - "version": "50.0.1", - "resolved": "https://registry.npmjs.org/eslint-plugin-unicorn/-/eslint-plugin-unicorn-50.0.1.tgz", - "integrity": "sha512-KxenCZxqSYW0GWHH18okDlOQcpezcitm5aOSz6EnobyJ6BIByiPDviQRjJIUAjG/tMN11958MxaQ+qCoU6lfDA==", + "version": "51.0.1", + "resolved": "https://registry.npmjs.org/eslint-plugin-unicorn/-/eslint-plugin-unicorn-51.0.1.tgz", + "integrity": "sha512-MuR/+9VuB0fydoI0nIn2RDA5WISRn4AsJyNSaNKLVwie9/ONvQhxOBbkfSICBPnzKrB77Fh6CZZXjgTt/4Latw==", "dev": true, "requires": { "@babel/helper-validator-identifier": "^7.22.20", @@ -7436,14 +7442,6 @@ "regjsparser": "^0.10.0", "semver": "^7.5.4", "strip-indent": "^3.0.0" - }, - "dependencies": { - "ci-info": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-4.0.0.tgz", - "integrity": "sha512-TdHqgGf9odd8SXNuxtUBVx8Nv+qZOejE6qyqiy5NtbYYQOeFa6zmHkxlPzmaLxWWHsU6nJmB7AETdVPi+2NBUg==", - "dev": true - } } }, "eslint-visitor-keys": { @@ -7801,7 +7799,7 @@ "@types/express": "^4.17.17", "@types/fluent-ffmpeg": "^2.1.21", "@types/imagemin": "^8.0.1", - "@types/jest": "29.5.11", + "@types/jest": "29.5.12", "@types/jest-when": "^3.5.2", "@types/lodash": "^4.14.197", "@types/mock-fs": "^4.13.1", @@ -7826,7 +7824,7 @@ "eslint": "^8.56.0", "eslint-config-prettier": "^9.1.0", "eslint-plugin-prettier": "^5.1.3", - "eslint-plugin-unicorn": "^50.0.1", + "eslint-plugin-unicorn": "^51.0.0", "exiftool-vendored": "~24.4.0", "exiftool-vendored.pl": "12.73", "fluent-ffmpeg": "^2.1.2", diff --git a/cli/package.json b/cli/package.json index 83451dbe47..ae51c796b3 100644 --- a/cli/package.json +++ b/cli/package.json @@ -28,7 +28,7 @@ "eslint": "^8.56.0", "eslint-config-prettier": "^9.1.0", "eslint-plugin-prettier": "^5.1.3", - "eslint-plugin-unicorn": "^50.0.1", + "eslint-plugin-unicorn": "^51.0.0", "glob": "^10.3.1", "immich": "file:../server", "mock-fs": "^5.2.0", diff --git a/server/package-lock.json b/server/package-lock.json index 3c94f10a07..eb50e0e6f1 100644 --- a/server/package-lock.json +++ b/server/package-lock.json @@ -83,7 +83,7 @@ "eslint": "^8.56.0", "eslint-config-prettier": "^9.1.0", "eslint-plugin-prettier": "^5.1.3", - "eslint-plugin-unicorn": "^50.0.1", + "eslint-plugin-unicorn": "^51.0.0", "jest": "^29.6.4", "jest-when": "^3.6.0", "mock-fs": "^5.2.0", @@ -5805,9 +5805,9 @@ } }, "node_modules/eslint-plugin-unicorn": { - "version": "50.0.1", - "resolved": "https://registry.npmjs.org/eslint-plugin-unicorn/-/eslint-plugin-unicorn-50.0.1.tgz", - "integrity": "sha512-KxenCZxqSYW0GWHH18okDlOQcpezcitm5aOSz6EnobyJ6BIByiPDviQRjJIUAjG/tMN11958MxaQ+qCoU6lfDA==", + "version": "51.0.1", + "resolved": "https://registry.npmjs.org/eslint-plugin-unicorn/-/eslint-plugin-unicorn-51.0.1.tgz", + "integrity": "sha512-MuR/+9VuB0fydoI0nIn2RDA5WISRn4AsJyNSaNKLVwie9/ONvQhxOBbkfSICBPnzKrB77Fh6CZZXjgTt/4Latw==", "dev": true, "dependencies": { "@babel/helper-validator-identifier": "^7.22.20", @@ -16772,9 +16772,9 @@ } }, "eslint-plugin-unicorn": { - "version": "50.0.1", - "resolved": "https://registry.npmjs.org/eslint-plugin-unicorn/-/eslint-plugin-unicorn-50.0.1.tgz", - "integrity": "sha512-KxenCZxqSYW0GWHH18okDlOQcpezcitm5aOSz6EnobyJ6BIByiPDviQRjJIUAjG/tMN11958MxaQ+qCoU6lfDA==", + "version": "51.0.1", + "resolved": "https://registry.npmjs.org/eslint-plugin-unicorn/-/eslint-plugin-unicorn-51.0.1.tgz", + "integrity": "sha512-MuR/+9VuB0fydoI0nIn2RDA5WISRn4AsJyNSaNKLVwie9/ONvQhxOBbkfSICBPnzKrB77Fh6CZZXjgTt/4Latw==", "dev": true, "requires": { "@babel/helper-validator-identifier": "^7.22.20", diff --git a/server/package.json b/server/package.json index 16c2042ecf..d5d2c62dc8 100644 --- a/server/package.json +++ b/server/package.json @@ -108,7 +108,7 @@ "eslint": "^8.56.0", "eslint-config-prettier": "^9.1.0", "eslint-plugin-prettier": "^5.1.3", - "eslint-plugin-unicorn": "^50.0.1", + "eslint-plugin-unicorn": "^51.0.0", "jest": "^29.6.4", "jest-when": "^3.6.0", "mock-fs": "^5.2.0", diff --git a/web/package-lock.json b/web/package-lock.json index 8ed9df2c72..9f20610d9b 100644 --- a/web/package-lock.json +++ b/web/package-lock.json @@ -44,7 +44,7 @@ "eslint": "^8.34.0", "eslint-config-prettier": "^9.1.0", "eslint-plugin-svelte": "^2.30.0", - "eslint-plugin-unicorn": "^50.0.1", + "eslint-plugin-unicorn": "^51.0.0", "factory.ts": "^1.3.0", "identity-obj-proxy": "^3.0.0", "postcss": "^8.4.21", @@ -3641,9 +3641,9 @@ "dev": true }, "node_modules/eslint-plugin-unicorn": { - "version": "50.0.1", - "resolved": "https://registry.npmjs.org/eslint-plugin-unicorn/-/eslint-plugin-unicorn-50.0.1.tgz", - "integrity": "sha512-KxenCZxqSYW0GWHH18okDlOQcpezcitm5aOSz6EnobyJ6BIByiPDviQRjJIUAjG/tMN11958MxaQ+qCoU6lfDA==", + "version": "51.0.1", + "resolved": "https://registry.npmjs.org/eslint-plugin-unicorn/-/eslint-plugin-unicorn-51.0.1.tgz", + "integrity": "sha512-MuR/+9VuB0fydoI0nIn2RDA5WISRn4AsJyNSaNKLVwie9/ONvQhxOBbkfSICBPnzKrB77Fh6CZZXjgTt/4Latw==", "dev": true, "dependencies": { "@babel/helper-validator-identifier": "^7.22.20", @@ -3698,9 +3698,9 @@ } }, "node_modules/eslint-plugin-unicorn/node_modules/semver": { - "version": "7.5.4", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz", - "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==", + "version": "7.6.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.0.tgz", + "integrity": "sha512-EnwXhrlwXMk9gKu5/flx5sv/an57AkRplG3hTK68W7FRDN+k+OWBj65M7719OkA82XLBxrcX0KSHj+X5COhOVg==", "dev": true, "dependencies": { "lru-cache": "^6.0.0" diff --git a/web/package.json b/web/package.json index 64961251fc..a1ead3d9a4 100644 --- a/web/package.json +++ b/web/package.json @@ -39,7 +39,7 @@ "eslint": "^8.34.0", "eslint-config-prettier": "^9.1.0", "eslint-plugin-svelte": "^2.30.0", - "eslint-plugin-unicorn": "^50.0.1", + "eslint-plugin-unicorn": "^51.0.0", "factory.ts": "^1.3.0", "identity-obj-proxy": "^3.0.0", "postcss": "^8.4.21", From b2775c445aa193c38b61cdc402f995163799baf7 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 6 Feb 2024 22:54:36 +0000 Subject: [PATCH 030/104] chore(deps): update @immich/cli (#6951) * chore(deps): update @immich/cli * bumpy --------- Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> Co-authored-by: Jonathan Jogenfors --- cli/package-lock.json | 202 +++++++++++++++++++++--------------------- cli/package.json | 6 +- 2 files changed, 104 insertions(+), 104 deletions(-) diff --git a/cli/package-lock.json b/cli/package-lock.json index 8324fdd9d0..c1adaf4571 100644 --- a/cli/package-lock.json +++ b/cli/package-lock.json @@ -13,13 +13,13 @@ }, "devDependencies": { "@immich/sdk": "file:../open-api/typescript-sdk", - "@testcontainers/postgresql": "^10.4.0", + "@testcontainers/postgresql": "^10.7.1", "@types/byte-size": "^8.1.0", "@types/cli-progress": "^3.11.0", "@types/mock-fs": "^4.13.1", "@types/node": "^20.3.1", - "@typescript-eslint/eslint-plugin": "^6.4.1", - "@typescript-eslint/parser": "^6.4.1", + "@typescript-eslint/eslint-plugin": "^6.21.0", + "@typescript-eslint/parser": "^6.21.0", "@vitest/coverage-v8": "^1.2.2", "byte-size": "^8.1.1", "cli-progress": "^3.12.0", @@ -1234,12 +1234,12 @@ "dev": true }, "node_modules/@testcontainers/postgresql": { - "version": "10.6.0", - "resolved": "https://registry.npmjs.org/@testcontainers/postgresql/-/postgresql-10.6.0.tgz", - "integrity": "sha512-gHYpsXkVLpCkJ0jg7xE5n8pogTNvw2LyhkXeJm04raH1yz020jcHAB2a1tRW1J2D8mM8WhFH+xH6pzH2ZggFdg==", + "version": "10.7.1", + "resolved": "https://registry.npmjs.org/@testcontainers/postgresql/-/postgresql-10.7.1.tgz", + "integrity": "sha512-2tlrD7vRNdi+nynFCNaGbjTTE7aUNk9Pipcu7PIkPGc8v1AxJdc1BnmI07I1yfW18kOqRi7fo7x4gOlqzAOXJQ==", "dev": true, "dependencies": { - "testcontainers": "^10.6.0" + "testcontainers": "^10.7.1" } }, "node_modules/@types/byte-size": { @@ -1353,16 +1353,16 @@ } }, "node_modules/@typescript-eslint/eslint-plugin": { - "version": "6.20.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-6.20.0.tgz", - "integrity": "sha512-fTwGQUnjhoYHeSF6m5pWNkzmDDdsKELYrOBxhjMrofPqCkoC2k3B2wvGHFxa1CTIqkEn88nlW1HVMztjo2K8Hg==", + "version": "6.21.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-6.21.0.tgz", + "integrity": "sha512-oy9+hTPCUFpngkEZUSzbf9MxI65wbKFoQYsgPdILTfbUldp5ovUuphZVe4i30emU9M/kP+T64Di0mxl7dSw3MA==", "dev": true, "dependencies": { "@eslint-community/regexpp": "^4.5.1", - "@typescript-eslint/scope-manager": "6.20.0", - "@typescript-eslint/type-utils": "6.20.0", - "@typescript-eslint/utils": "6.20.0", - "@typescript-eslint/visitor-keys": "6.20.0", + "@typescript-eslint/scope-manager": "6.21.0", + "@typescript-eslint/type-utils": "6.21.0", + "@typescript-eslint/utils": "6.21.0", + "@typescript-eslint/visitor-keys": "6.21.0", "debug": "^4.3.4", "graphemer": "^1.4.0", "ignore": "^5.2.4", @@ -1388,15 +1388,15 @@ } }, "node_modules/@typescript-eslint/parser": { - "version": "6.20.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-6.20.0.tgz", - "integrity": "sha512-bYerPDF/H5v6V76MdMYhjwmwgMA+jlPVqjSDq2cRqMi8bP5sR3Z+RLOiOMad3nsnmDVmn2gAFCyNgh/dIrfP/w==", + "version": "6.21.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-6.21.0.tgz", + "integrity": "sha512-tbsV1jPne5CkFQCgPBcDOt30ItF7aJoZL997JSF7MhGQqOeT3svWRYxiqlfA5RUdlHN6Fi+EI9bxqbdyAUZjYQ==", "dev": true, "dependencies": { - "@typescript-eslint/scope-manager": "6.20.0", - "@typescript-eslint/types": "6.20.0", - "@typescript-eslint/typescript-estree": "6.20.0", - "@typescript-eslint/visitor-keys": "6.20.0", + "@typescript-eslint/scope-manager": "6.21.0", + "@typescript-eslint/types": "6.21.0", + "@typescript-eslint/typescript-estree": "6.21.0", + "@typescript-eslint/visitor-keys": "6.21.0", "debug": "^4.3.4" }, "engines": { @@ -1416,13 +1416,13 @@ } }, "node_modules/@typescript-eslint/scope-manager": { - "version": "6.20.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-6.20.0.tgz", - "integrity": "sha512-p4rvHQRDTI1tGGMDFQm+GtxP1ZHyAh64WANVoyEcNMpaTFn3ox/3CcgtIlELnRfKzSs/DwYlDccJEtr3O6qBvA==", + "version": "6.21.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-6.21.0.tgz", + "integrity": "sha512-OwLUIWZJry80O99zvqXVEioyniJMa+d2GrqpUTqi5/v5D5rOrppJVBPa0yKCblcigC0/aYAzxxqQ1B+DS2RYsg==", "dev": true, "dependencies": { - "@typescript-eslint/types": "6.20.0", - "@typescript-eslint/visitor-keys": "6.20.0" + "@typescript-eslint/types": "6.21.0", + "@typescript-eslint/visitor-keys": "6.21.0" }, "engines": { "node": "^16.0.0 || >=18.0.0" @@ -1433,13 +1433,13 @@ } }, "node_modules/@typescript-eslint/type-utils": { - "version": "6.20.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-6.20.0.tgz", - "integrity": "sha512-qnSobiJQb1F5JjN0YDRPHruQTrX7ICsmltXhkV536mp4idGAYrIyr47zF/JmkJtEcAVnIz4gUYJ7gOZa6SmN4g==", + "version": "6.21.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-6.21.0.tgz", + "integrity": "sha512-rZQI7wHfao8qMX3Rd3xqeYSMCL3SoiSQLBATSiVKARdFGCYSRvmViieZjqc58jKgs8Y8i9YvVVhRbHSTA4VBag==", "dev": true, "dependencies": { - "@typescript-eslint/typescript-estree": "6.20.0", - "@typescript-eslint/utils": "6.20.0", + "@typescript-eslint/typescript-estree": "6.21.0", + "@typescript-eslint/utils": "6.21.0", "debug": "^4.3.4", "ts-api-utils": "^1.0.1" }, @@ -1460,9 +1460,9 @@ } }, "node_modules/@typescript-eslint/types": { - "version": "6.20.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-6.20.0.tgz", - "integrity": "sha512-MM9mfZMAhiN4cOEcUOEx+0HmuaW3WBfukBZPCfwSqFnQy0grXYtngKCqpQN339X3RrwtzspWJrpbrupKYUSBXQ==", + "version": "6.21.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-6.21.0.tgz", + "integrity": "sha512-1kFmZ1rOm5epu9NZEZm1kckCDGj5UJEf7P1kliH4LKu/RkwpsfqqGmY2OOcUs18lSlQBKLDYBOGxRVtrMN5lpg==", "dev": true, "engines": { "node": "^16.0.0 || >=18.0.0" @@ -1473,13 +1473,13 @@ } }, "node_modules/@typescript-eslint/typescript-estree": { - "version": "6.20.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-6.20.0.tgz", - "integrity": "sha512-RnRya9q5m6YYSpBN7IzKu9FmLcYtErkDkc8/dKv81I9QiLLtVBHrjz+Ev/crAqgMNW2FCsoZF4g2QUylMnJz+g==", + "version": "6.21.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-6.21.0.tgz", + "integrity": "sha512-6npJTkZcO+y2/kr+z0hc4HwNfrrP4kNYh57ek7yCNlrBjWQ1Y0OS7jiZTkgumrvkX5HkEKXFZkkdFNkaW2wmUQ==", "dev": true, "dependencies": { - "@typescript-eslint/types": "6.20.0", - "@typescript-eslint/visitor-keys": "6.20.0", + "@typescript-eslint/types": "6.21.0", + "@typescript-eslint/visitor-keys": "6.21.0", "debug": "^4.3.4", "globby": "^11.1.0", "is-glob": "^4.0.3", @@ -1525,17 +1525,17 @@ } }, "node_modules/@typescript-eslint/utils": { - "version": "6.20.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-6.20.0.tgz", - "integrity": "sha512-/EKuw+kRu2vAqCoDwDCBtDRU6CTKbUmwwI7SH7AashZ+W+7o8eiyy6V2cdOqN49KsTcASWsC5QeghYuRDTyOOg==", + "version": "6.21.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-6.21.0.tgz", + "integrity": "sha512-NfWVaC8HP9T8cbKQxHcsJBY5YE1O33+jpMwN45qzWWaPDZgLIbo12toGMWnmhvCpd3sIxkpDw3Wv1B3dYrbDQQ==", "dev": true, "dependencies": { "@eslint-community/eslint-utils": "^4.4.0", "@types/json-schema": "^7.0.12", "@types/semver": "^7.5.0", - "@typescript-eslint/scope-manager": "6.20.0", - "@typescript-eslint/types": "6.20.0", - "@typescript-eslint/typescript-estree": "6.20.0", + "@typescript-eslint/scope-manager": "6.21.0", + "@typescript-eslint/types": "6.21.0", + "@typescript-eslint/typescript-estree": "6.21.0", "semver": "^7.5.4" }, "engines": { @@ -1550,12 +1550,12 @@ } }, "node_modules/@typescript-eslint/visitor-keys": { - "version": "6.20.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-6.20.0.tgz", - "integrity": "sha512-E8Cp98kRe4gKHjJD4NExXKz/zOJ1A2hhZc+IMVD6i7w4yjIvh6VyuRI0gRtxAsXtoC35uGMaQ9rjI2zJaXDEAw==", + "version": "6.21.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-6.21.0.tgz", + "integrity": "sha512-JJtkDduxLi9bivAB+cYOVMtbkqdPOhZ+ZI5LC47MIRrDV4Yn2o+ZnW10Nkmr28xRpSpdJ6Sm42Hjf2+REYXm0A==", "dev": true, "dependencies": { - "@typescript-eslint/types": "6.20.0", + "@typescript-eslint/types": "6.21.0", "eslint-visitor-keys": "^3.4.1" }, "engines": { @@ -4957,9 +4957,9 @@ } }, "node_modules/testcontainers": { - "version": "10.6.0", - "resolved": "https://registry.npmjs.org/testcontainers/-/testcontainers-10.6.0.tgz", - "integrity": "sha512-FDJ3o3J8IMu1V7Uc6lNZ2MAD8+BV4HdpR/Vf5mHtgYHKdn6k1EbGFwtnvVNOxanJ99FCjf/EU8eA5ZQ4yjlsGA==", + "version": "10.7.1", + "resolved": "https://registry.npmjs.org/testcontainers/-/testcontainers-10.7.1.tgz", + "integrity": "sha512-JarbT6o7fv1siUts4tGv3wBoYrWKxjla69+5QWG9+bcd4l+ECJ3ikfGD/hpXRmRBsnjzeWyV+tL9oWOBRzk+lA==", "dev": true, "dependencies": { "@balena/dockerignore": "^1.0.2", @@ -6354,12 +6354,12 @@ "dev": true }, "@testcontainers/postgresql": { - "version": "10.6.0", - "resolved": "https://registry.npmjs.org/@testcontainers/postgresql/-/postgresql-10.6.0.tgz", - "integrity": "sha512-gHYpsXkVLpCkJ0jg7xE5n8pogTNvw2LyhkXeJm04raH1yz020jcHAB2a1tRW1J2D8mM8WhFH+xH6pzH2ZggFdg==", + "version": "10.7.1", + "resolved": "https://registry.npmjs.org/@testcontainers/postgresql/-/postgresql-10.7.1.tgz", + "integrity": "sha512-2tlrD7vRNdi+nynFCNaGbjTTE7aUNk9Pipcu7PIkPGc8v1AxJdc1BnmI07I1yfW18kOqRi7fo7x4gOlqzAOXJQ==", "dev": true, "requires": { - "testcontainers": "^10.6.0" + "testcontainers": "^10.7.1" } }, "@types/byte-size": { @@ -6475,16 +6475,16 @@ } }, "@typescript-eslint/eslint-plugin": { - "version": "6.20.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-6.20.0.tgz", - "integrity": "sha512-fTwGQUnjhoYHeSF6m5pWNkzmDDdsKELYrOBxhjMrofPqCkoC2k3B2wvGHFxa1CTIqkEn88nlW1HVMztjo2K8Hg==", + "version": "6.21.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-6.21.0.tgz", + "integrity": "sha512-oy9+hTPCUFpngkEZUSzbf9MxI65wbKFoQYsgPdILTfbUldp5ovUuphZVe4i30emU9M/kP+T64Di0mxl7dSw3MA==", "dev": true, "requires": { "@eslint-community/regexpp": "^4.5.1", - "@typescript-eslint/scope-manager": "6.20.0", - "@typescript-eslint/type-utils": "6.20.0", - "@typescript-eslint/utils": "6.20.0", - "@typescript-eslint/visitor-keys": "6.20.0", + "@typescript-eslint/scope-manager": "6.21.0", + "@typescript-eslint/type-utils": "6.21.0", + "@typescript-eslint/utils": "6.21.0", + "@typescript-eslint/visitor-keys": "6.21.0", "debug": "^4.3.4", "graphemer": "^1.4.0", "ignore": "^5.2.4", @@ -6494,54 +6494,54 @@ } }, "@typescript-eslint/parser": { - "version": "6.20.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-6.20.0.tgz", - "integrity": "sha512-bYerPDF/H5v6V76MdMYhjwmwgMA+jlPVqjSDq2cRqMi8bP5sR3Z+RLOiOMad3nsnmDVmn2gAFCyNgh/dIrfP/w==", + "version": "6.21.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-6.21.0.tgz", + "integrity": "sha512-tbsV1jPne5CkFQCgPBcDOt30ItF7aJoZL997JSF7MhGQqOeT3svWRYxiqlfA5RUdlHN6Fi+EI9bxqbdyAUZjYQ==", "dev": true, "requires": { - "@typescript-eslint/scope-manager": "6.20.0", - "@typescript-eslint/types": "6.20.0", - "@typescript-eslint/typescript-estree": "6.20.0", - "@typescript-eslint/visitor-keys": "6.20.0", + "@typescript-eslint/scope-manager": "6.21.0", + "@typescript-eslint/types": "6.21.0", + "@typescript-eslint/typescript-estree": "6.21.0", + "@typescript-eslint/visitor-keys": "6.21.0", "debug": "^4.3.4" } }, "@typescript-eslint/scope-manager": { - "version": "6.20.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-6.20.0.tgz", - "integrity": "sha512-p4rvHQRDTI1tGGMDFQm+GtxP1ZHyAh64WANVoyEcNMpaTFn3ox/3CcgtIlELnRfKzSs/DwYlDccJEtr3O6qBvA==", + "version": "6.21.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-6.21.0.tgz", + "integrity": "sha512-OwLUIWZJry80O99zvqXVEioyniJMa+d2GrqpUTqi5/v5D5rOrppJVBPa0yKCblcigC0/aYAzxxqQ1B+DS2RYsg==", "dev": true, "requires": { - "@typescript-eslint/types": "6.20.0", - "@typescript-eslint/visitor-keys": "6.20.0" + "@typescript-eslint/types": "6.21.0", + "@typescript-eslint/visitor-keys": "6.21.0" } }, "@typescript-eslint/type-utils": { - "version": "6.20.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-6.20.0.tgz", - "integrity": "sha512-qnSobiJQb1F5JjN0YDRPHruQTrX7ICsmltXhkV536mp4idGAYrIyr47zF/JmkJtEcAVnIz4gUYJ7gOZa6SmN4g==", + "version": "6.21.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-6.21.0.tgz", + "integrity": "sha512-rZQI7wHfao8qMX3Rd3xqeYSMCL3SoiSQLBATSiVKARdFGCYSRvmViieZjqc58jKgs8Y8i9YvVVhRbHSTA4VBag==", "dev": true, "requires": { - "@typescript-eslint/typescript-estree": "6.20.0", - "@typescript-eslint/utils": "6.20.0", + "@typescript-eslint/typescript-estree": "6.21.0", + "@typescript-eslint/utils": "6.21.0", "debug": "^4.3.4", "ts-api-utils": "^1.0.1" } }, "@typescript-eslint/types": { - "version": "6.20.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-6.20.0.tgz", - "integrity": "sha512-MM9mfZMAhiN4cOEcUOEx+0HmuaW3WBfukBZPCfwSqFnQy0grXYtngKCqpQN339X3RrwtzspWJrpbrupKYUSBXQ==", + "version": "6.21.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-6.21.0.tgz", + "integrity": "sha512-1kFmZ1rOm5epu9NZEZm1kckCDGj5UJEf7P1kliH4LKu/RkwpsfqqGmY2OOcUs18lSlQBKLDYBOGxRVtrMN5lpg==", "dev": true }, "@typescript-eslint/typescript-estree": { - "version": "6.20.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-6.20.0.tgz", - "integrity": "sha512-RnRya9q5m6YYSpBN7IzKu9FmLcYtErkDkc8/dKv81I9QiLLtVBHrjz+Ev/crAqgMNW2FCsoZF4g2QUylMnJz+g==", + "version": "6.21.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-6.21.0.tgz", + "integrity": "sha512-6npJTkZcO+y2/kr+z0hc4HwNfrrP4kNYh57ek7yCNlrBjWQ1Y0OS7jiZTkgumrvkX5HkEKXFZkkdFNkaW2wmUQ==", "dev": true, "requires": { - "@typescript-eslint/types": "6.20.0", - "@typescript-eslint/visitor-keys": "6.20.0", + "@typescript-eslint/types": "6.21.0", + "@typescript-eslint/visitor-keys": "6.21.0", "debug": "^4.3.4", "globby": "^11.1.0", "is-glob": "^4.0.3", @@ -6571,27 +6571,27 @@ } }, "@typescript-eslint/utils": { - "version": "6.20.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-6.20.0.tgz", - "integrity": "sha512-/EKuw+kRu2vAqCoDwDCBtDRU6CTKbUmwwI7SH7AashZ+W+7o8eiyy6V2cdOqN49KsTcASWsC5QeghYuRDTyOOg==", + "version": "6.21.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-6.21.0.tgz", + "integrity": "sha512-NfWVaC8HP9T8cbKQxHcsJBY5YE1O33+jpMwN45qzWWaPDZgLIbo12toGMWnmhvCpd3sIxkpDw3Wv1B3dYrbDQQ==", "dev": true, "requires": { "@eslint-community/eslint-utils": "^4.4.0", "@types/json-schema": "^7.0.12", "@types/semver": "^7.5.0", - "@typescript-eslint/scope-manager": "6.20.0", - "@typescript-eslint/types": "6.20.0", - "@typescript-eslint/typescript-estree": "6.20.0", + "@typescript-eslint/scope-manager": "6.21.0", + "@typescript-eslint/types": "6.21.0", + "@typescript-eslint/typescript-estree": "6.21.0", "semver": "^7.5.4" } }, "@typescript-eslint/visitor-keys": { - "version": "6.20.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-6.20.0.tgz", - "integrity": "sha512-E8Cp98kRe4gKHjJD4NExXKz/zOJ1A2hhZc+IMVD6i7w4yjIvh6VyuRI0gRtxAsXtoC35uGMaQ9rjI2zJaXDEAw==", + "version": "6.21.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-6.21.0.tgz", + "integrity": "sha512-JJtkDduxLi9bivAB+cYOVMtbkqdPOhZ+ZI5LC47MIRrDV4Yn2o+ZnW10Nkmr28xRpSpdJ6Sm42Hjf2+REYXm0A==", "dev": true, "requires": { - "@typescript-eslint/types": "6.20.0", + "@typescript-eslint/types": "6.21.0", "eslint-visitor-keys": "^3.4.1" } }, @@ -9210,9 +9210,9 @@ } }, "testcontainers": { - "version": "10.6.0", - "resolved": "https://registry.npmjs.org/testcontainers/-/testcontainers-10.6.0.tgz", - "integrity": "sha512-FDJ3o3J8IMu1V7Uc6lNZ2MAD8+BV4HdpR/Vf5mHtgYHKdn6k1EbGFwtnvVNOxanJ99FCjf/EU8eA5ZQ4yjlsGA==", + "version": "10.7.1", + "resolved": "https://registry.npmjs.org/testcontainers/-/testcontainers-10.7.1.tgz", + "integrity": "sha512-JarbT6o7fv1siUts4tGv3wBoYrWKxjla69+5QWG9+bcd4l+ECJ3ikfGD/hpXRmRBsnjzeWyV+tL9oWOBRzk+lA==", "dev": true, "requires": { "@balena/dockerignore": "^1.0.2", diff --git a/cli/package.json b/cli/package.json index ae51c796b3..2f9d436d74 100644 --- a/cli/package.json +++ b/cli/package.json @@ -14,13 +14,13 @@ ], "devDependencies": { "@immich/sdk": "file:../open-api/typescript-sdk", - "@testcontainers/postgresql": "^10.4.0", + "@testcontainers/postgresql": "^10.7.1", "@types/byte-size": "^8.1.0", "@types/cli-progress": "^3.11.0", "@types/mock-fs": "^4.13.1", "@types/node": "^20.3.1", - "@typescript-eslint/eslint-plugin": "^6.4.1", - "@typescript-eslint/parser": "^6.4.1", + "@typescript-eslint/eslint-plugin": "^6.21.0", + "@typescript-eslint/parser": "^6.21.0", "@vitest/coverage-v8": "^1.2.2", "byte-size": "^8.1.1", "cli-progress": "^3.12.0", From 56b06438906a8eff4113f58fd5922ac22bde38bd Mon Sep 17 00:00:00 2001 From: Mert <101130780+mertalev@users.noreply.github.com> Date: Tue, 6 Feb 2024 21:46:38 -0500 Subject: [PATCH 031/104] feat(server)!: pgvecto.rs 0.2 and pgvector compatibility (#6785) * basic changes update version check set ef_search for clip * pgvector compatibility Revert "pgvector compatibility" This reverts commit 2b66a52aa4097dd27da58138c5288fd87cb9b24a. pgvector compatibility: minimal edition pgvector startup check * update extension at startup * wording shortened vector extension variable name * nightly docker * fixed version checks * update tests add tests for updating extension remove unnecessary check * simplify `getRuntimeConfig` * wording * reindex on minor version update * 0.2 upgrade testing update prod compose * acquire lock for init * wip vector down on shutdown * use upgrade helper * update image tag * refine restart check check error message * test reindex testing upstream fix formatting fixed reindexing * use enum in signature * fix tests remove unused code * add reindexing tests * update to official 0.2 remove alpha from version name * add warning test if restart required * update test image to 0.2.0 * linting and test cleanup * formatting * update sql * wording * handle setting search path for new and existing databases * handle new db in reindex check * fix post-update reindexing * get dim size * formatting * use vbase * handle different db name * update sql * linting * fix suggested env --- .github/workflows/test.yml | 2 +- cli/test/e2e/setup.ts | 2 +- docker/docker-compose.dev.yml | 2 +- docker/docker-compose.prod.yml | 5 +- docker/docker-compose.yml | 2 +- server/e2e/api/setup.ts | 2 +- server/e2e/docker-compose.server-e2e.yml | 2 +- server/e2e/jobs/setup.ts | 2 +- .../domain/database/database.service.spec.ts | 236 ++++++++++++------ .../src/domain/database/database.service.ts | 183 ++++++++++---- server/src/domain/domain.config.ts | 1 + server/src/domain/domain.constant.spec.ts | 62 ++--- server/src/domain/domain.constant.ts | 36 ++- .../repositories/database.repository.ts | 26 ++ .../repositories/smart-info.repository.ts | 2 +- server/src/infra/database.config.ts | 4 + server/src/infra/logger.ts | 2 +- .../migrations/1700713871511-UsePgVectors.ts | 4 +- .../1700713994428-AddCLIPEmbeddingIndex.ts | 14 +- .../1700714033632-AddFaceEmbeddingIndex.ts | 14 +- .../1707000751533-AddVectorsToSearchPath.ts | 14 ++ .../infra/repositories/database.repository.ts | 168 ++++++++++++- .../repositories/smart-info.repository.ts | 85 ++++--- .../src/infra/sql/smart.info.repository.sql | 20 +- .../repositories/database.repository.mock.ts | 6 + 25 files changed, 650 insertions(+), 246 deletions(-) create mode 100644 server/src/infra/migrations/1707000751533-AddVectorsToSearchPath.ts diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 58761eea05..d9e7df74ad 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -275,7 +275,7 @@ jobs: runs-on: ubuntu-latest services: postgres: - image: tensorchord/pgvecto-rs:pg14-v0.1.11@sha256:0335a1a22f8c5dd1b697f14f079934f5152eaaa216c09b61e293be285491f8ee + image: tensorchord/pgvecto-rs:pg14-v0.2.0 env: POSTGRES_PASSWORD: postgres POSTGRES_USER: postgres diff --git a/cli/test/e2e/setup.ts b/cli/test/e2e/setup.ts index 52b2ae082c..fb1d939eba 100644 --- a/cli/test/e2e/setup.ts +++ b/cli/test/e2e/setup.ts @@ -25,7 +25,7 @@ export default async () => { if (process.env.DB_HOSTNAME === undefined) { // DB hostname not set which likely means we're not running e2e through docker compose. Start a local postgres container. - const pg = await new PostgreSqlContainer('tensorchord/pgvecto-rs:pg14-v0.1.11') + const pg = await new PostgreSqlContainer('tensorchord/pgvecto-rs:pg14-v0.2.0') .withExposedPorts(5432) .withDatabase('immich') .withUsername('postgres') diff --git a/docker/docker-compose.dev.yml b/docker/docker-compose.dev.yml index 5290e990e2..e380be4965 100644 --- a/docker/docker-compose.dev.yml +++ b/docker/docker-compose.dev.yml @@ -103,7 +103,7 @@ services: database: container_name: immich_postgres - image: tensorchord/pgvecto-rs:pg14-v0.1.11@sha256:0335a1a22f8c5dd1b697f14f079934f5152eaaa216c09b61e293be285491f8ee + image: tensorchord/pgvecto-rs:pg14-v0.2.0 env_file: - .env environment: diff --git a/docker/docker-compose.prod.yml b/docker/docker-compose.prod.yml index 04215b757b..857aa31540 100644 --- a/docker/docker-compose.prod.yml +++ b/docker/docker-compose.prod.yml @@ -61,7 +61,7 @@ services: database: container_name: immich_postgres - image: tensorchord/pgvecto-rs:pg14-v0.1.11@sha256:0335a1a22f8c5dd1b697f14f079934f5152eaaa216c09b61e293be285491f8ee + image: tensorchord/pgvecto-rs:pg14-v0.2.0 env_file: - .env environment: @@ -70,7 +70,8 @@ services: POSTGRES_DB: ${DB_DATABASE_NAME} volumes: - ${UPLOAD_LOCATION}/postgres:/var/lib/postgresql/data - restart: always + ports: + - 5432:5432 volumes: model-cache: diff --git a/docker/docker-compose.yml b/docker/docker-compose.yml index a6e6aa26ff..a9d8e2b38c 100644 --- a/docker/docker-compose.yml +++ b/docker/docker-compose.yml @@ -65,7 +65,7 @@ services: database: container_name: immich_postgres - image: tensorchord/pgvecto-rs:pg14-v0.1.11@sha256:0335a1a22f8c5dd1b697f14f079934f5152eaaa216c09b61e293be285491f8ee + image: tensorchord/pgvecto-rs:pg14-v0.2.0 env_file: - .env environment: diff --git a/server/e2e/api/setup.ts b/server/e2e/api/setup.ts index 7223a1c028..8d44b07cbb 100644 --- a/server/e2e/api/setup.ts +++ b/server/e2e/api/setup.ts @@ -1,7 +1,7 @@ import { PostgreSqlContainer } from '@testcontainers/postgresql'; export default async () => { - const pg = await new PostgreSqlContainer('tensorchord/pgvecto-rs:pg14-v0.1.11') + const pg = await new PostgreSqlContainer('tensorchord/pgvecto-rs:pg14-v0.2.0') .withDatabase('immich') .withUsername('postgres') .withPassword('postgres') diff --git a/server/e2e/docker-compose.server-e2e.yml b/server/e2e/docker-compose.server-e2e.yml index c9d656cedb..708ae2ca34 100644 --- a/server/e2e/docker-compose.server-e2e.yml +++ b/server/e2e/docker-compose.server-e2e.yml @@ -21,7 +21,7 @@ services: - database database: - image: tensorchord/pgvecto-rs:pg14-v0.1.11@sha256:0335a1a22f8c5dd1b697f14f079934f5152eaaa216c09b61e293be285491f8ee + image: tensorchord/pgvecto-rs:pg14-v0.2.0 command: -c fsync=off -c shared_preload_libraries=vectors.so environment: POSTGRES_PASSWORD: postgres diff --git a/server/e2e/jobs/setup.ts b/server/e2e/jobs/setup.ts index 601d99cc28..d1f566d372 100644 --- a/server/e2e/jobs/setup.ts +++ b/server/e2e/jobs/setup.ts @@ -25,7 +25,7 @@ export default async () => { if (process.env.DB_HOSTNAME === undefined) { // DB hostname not set which likely means we're not running e2e through docker compose. Start a local postgres container. - const pg = await new PostgreSqlContainer('tensorchord/pgvecto-rs:pg14-v0.1.11') + const pg = await new PostgreSqlContainer('tensorchord/pgvecto-rs:pg14-v0.2.0') .withExposedPorts(5432) .withDatabase('immich') .withUsername('postgres') diff --git a/server/src/domain/database/database.service.spec.ts b/server/src/domain/database/database.service.spec.ts index 7608f61111..703805b065 100644 --- a/server/src/domain/database/database.service.spec.ts +++ b/server/src/domain/database/database.service.spec.ts @@ -1,41 +1,65 @@ -import { DatabaseExtension, DatabaseService, IDatabaseRepository, Version } from '@app/domain'; +import { + DatabaseExtension, + DatabaseService, + IDatabaseRepository, + VectorIndex, + Version, + VersionType, +} from '@app/domain'; import { ImmichLogger } from '@app/infra/logger'; import { newDatabaseRepositoryMock } from '@test'; describe(DatabaseService.name, () => { let sut: DatabaseService; let databaseMock: jest.Mocked; - let fatalLog: jest.SpyInstance; beforeEach(async () => { databaseMock = newDatabaseRepositoryMock(); - fatalLog = jest.spyOn(ImmichLogger.prototype, 'fatal'); sut = new DatabaseService(databaseMock); - - sut.minVectorsVersion = new Version(0, 1, 1); - sut.maxVectorsVersion = new Version(0, 1, 11); - }); - - afterEach(() => { - fatalLog.mockRestore(); }); it('should work', () => { expect(sut).toBeDefined(); }); - describe('init', () => { - it('should resolve successfully if minimum supported PostgreSQL and vectors version are installed', async () => { + describe.each([ + [{ vectorExt: DatabaseExtension.VECTORS, extName: 'pgvecto.rs', minVersion: new Version(0, 1, 1) }], + [{ vectorExt: DatabaseExtension.VECTOR, extName: 'pgvector', minVersion: new Version(0, 5, 0) }], + ] as const)('init', ({ vectorExt, extName, minVersion }) => { + let fatalLog: jest.SpyInstance; + let errorLog: jest.SpyInstance; + let warnLog: jest.SpyInstance; + + beforeEach(async () => { + fatalLog = jest.spyOn(ImmichLogger.prototype, 'fatal'); + errorLog = jest.spyOn(ImmichLogger.prototype, 'error'); + warnLog = jest.spyOn(ImmichLogger.prototype, 'warn'); + databaseMock.getPreferredVectorExtension.mockReturnValue(vectorExt); + databaseMock.getExtensionVersion.mockResolvedValue(minVersion); + + sut = new DatabaseService(databaseMock); + + sut.minVectorVersion = minVersion; + sut.minVectorsVersion = minVersion; + sut.vectorVersionPin = VersionType.MINOR; + sut.vectorsVersionPin = VersionType.MINOR; + }); + + afterEach(() => { + fatalLog.mockRestore(); + warnLog.mockRestore(); + }); + + it(`should resolve successfully if minimum supported PostgreSQL and ${extName} version are installed`, async () => { databaseMock.getPostgresVersion.mockResolvedValueOnce(new Version(14, 0, 0)); - databaseMock.getExtensionVersion.mockResolvedValueOnce(new Version(0, 1, 1)); await expect(sut.init()).resolves.toBeUndefined(); - expect(databaseMock.getPostgresVersion).toHaveBeenCalledTimes(2); - expect(databaseMock.createExtension).toHaveBeenCalledWith(DatabaseExtension.VECTORS); + expect(databaseMock.getPostgresVersion).toHaveBeenCalled(); + expect(databaseMock.createExtension).toHaveBeenCalledWith(vectorExt); expect(databaseMock.createExtension).toHaveBeenCalledTimes(1); - expect(databaseMock.getExtensionVersion).toHaveBeenCalledTimes(1); + expect(databaseMock.getExtensionVersion).toHaveBeenCalled(); expect(databaseMock.runMigrations).toHaveBeenCalledTimes(1); expect(fatalLog).not.toHaveBeenCalled(); }); @@ -43,112 +67,162 @@ describe(DatabaseService.name, () => { it('should throw an error if PostgreSQL version is below minimum supported version', async () => { databaseMock.getPostgresVersion.mockResolvedValueOnce(new Version(13, 0, 0)); - await expect(sut.init()).rejects.toThrow(/PostgreSQL version is 13/s); + await expect(sut.init()).rejects.toThrow('PostgreSQL version is 13'); expect(databaseMock.getPostgresVersion).toHaveBeenCalledTimes(1); }); - it('should resolve successfully if minimum supported vectors version is installed', async () => { - databaseMock.getExtensionVersion.mockResolvedValueOnce(new Version(0, 1, 1)); - + it(`should resolve successfully if minimum supported ${extName} version is installed`, async () => { await expect(sut.init()).resolves.toBeUndefined(); - expect(databaseMock.createExtension).toHaveBeenCalledWith(DatabaseExtension.VECTORS); + expect(databaseMock.createExtension).toHaveBeenCalledWith(vectorExt); expect(databaseMock.createExtension).toHaveBeenCalledTimes(1); - expect(databaseMock.getExtensionVersion).toHaveBeenCalledTimes(1); expect(databaseMock.runMigrations).toHaveBeenCalledTimes(1); expect(fatalLog).not.toHaveBeenCalled(); }); - it('should resolve successfully if maximum supported vectors version is installed', async () => { - databaseMock.getExtensionVersion.mockResolvedValueOnce(new Version(0, 1, 11)); + it(`should throw an error if ${extName} version is not installed even after createVectorExtension`, async () => { + databaseMock.getExtensionVersion.mockResolvedValue(null); - await expect(sut.init()).resolves.toBeUndefined(); + await expect(sut.init()).rejects.toThrow(`Unexpected: ${extName} extension is not installed.`); - expect(databaseMock.createExtension).toHaveBeenCalledWith(DatabaseExtension.VECTORS); - expect(databaseMock.createExtension).toHaveBeenCalledTimes(1); - expect(databaseMock.getExtensionVersion).toHaveBeenCalledTimes(1); - expect(databaseMock.runMigrations).toHaveBeenCalledTimes(1); - expect(fatalLog).not.toHaveBeenCalled(); - }); - - it('should throw an error if vectors version is not installed even after createVectors', async () => { - databaseMock.getExtensionVersion.mockResolvedValueOnce(null); - - await expect(sut.init()).rejects.toThrow('Unexpected: The pgvecto.rs extension is not installed.'); - - expect(databaseMock.getExtensionVersion).toHaveBeenCalledTimes(1); expect(databaseMock.createExtension).toHaveBeenCalledTimes(1); expect(databaseMock.runMigrations).not.toHaveBeenCalled(); }); - it('should throw an error if vectors version is below minimum supported version', async () => { - databaseMock.getExtensionVersion.mockResolvedValueOnce(new Version(0, 0, 1)); - - await expect(sut.init()).rejects.toThrow(/('tensorchord\/pgvecto-rs:pg14-v0.1.11')/s); - - expect(databaseMock.getExtensionVersion).toHaveBeenCalledTimes(1); - expect(databaseMock.runMigrations).not.toHaveBeenCalled(); - }); - - it('should throw an error if vectors version is above maximum supported version', async () => { - databaseMock.getExtensionVersion.mockResolvedValueOnce(new Version(0, 1, 12)); - - await expect(sut.init()).rejects.toThrow( - /('DROP EXTENSION IF EXISTS vectors').*('tensorchord\/pgvecto-rs:pg14-v0\.1\.11')/s, + it(`should throw an error if ${extName} version is below minimum supported version`, async () => { + databaseMock.getExtensionVersion.mockResolvedValue( + new Version(minVersion.major, minVersion.minor - 1, minVersion.patch), ); - expect(databaseMock.getExtensionVersion).toHaveBeenCalledTimes(1); + await expect(sut.init()).rejects.toThrow(extName); + expect(databaseMock.runMigrations).not.toHaveBeenCalled(); }); - it('should throw an error if vectors version is a nightly', async () => { - databaseMock.getExtensionVersion.mockResolvedValueOnce(new Version(0, 0, 0)); + it.each([ + { type: VersionType.EQUAL, max: 'no', actual: 'patch' }, + { type: VersionType.PATCH, max: 'patch', actual: 'minor' }, + { type: VersionType.MINOR, max: 'minor', actual: 'major' }, + ] as const)( + `should throw an error if $max upgrade from min version is allowed and ${extName} version is $actual`, + async ({ type, actual }) => { + const version = new Version(minVersion.major, minVersion.minor, minVersion.patch); + version[actual] = minVersion[actual] + 1; + databaseMock.getExtensionVersion.mockResolvedValue(version); + if (vectorExt === DatabaseExtension.VECTOR) { + sut.minVectorVersion = minVersion; + sut.vectorVersionPin = type; + } else { + sut.minVectorsVersion = minVersion; + sut.vectorsVersionPin = type; + } - await expect(sut.init()).rejects.toThrow( - /(nightly).*('DROP EXTENSION IF EXISTS vectors').*('tensorchord\/pgvecto-rs:pg14-v0\.1\.11')/s, - ); + await expect(sut.init()).rejects.toThrow(extName); + + expect(databaseMock.runMigrations).not.toHaveBeenCalled(); + }, + ); + + it(`should throw an error if ${extName} version is a nightly`, async () => { + databaseMock.getExtensionVersion.mockResolvedValue(new Version(0, 0, 0)); + + await expect(sut.init()).rejects.toThrow(extName); - expect(databaseMock.getExtensionVersion).toHaveBeenCalledTimes(1); expect(databaseMock.createExtension).toHaveBeenCalledTimes(1); expect(databaseMock.runMigrations).not.toHaveBeenCalled(); }); - it('should throw error if vectors extension could not be created', async () => { - databaseMock.createExtension.mockRejectedValueOnce(new Error('Failed to create extension')); + it(`should throw error if ${extName} extension could not be created`, async () => { + databaseMock.createExtension.mockRejectedValue(new Error('Failed to create extension')); await expect(sut.init()).rejects.toThrow('Failed to create extension'); expect(fatalLog).toHaveBeenCalledTimes(1); - expect(fatalLog.mock.calls[0][0]).toMatch(/('tensorchord\/pgvecto-rs:pg14-v0\.1\.11').*(v1\.91\.0)/s); expect(databaseMock.createExtension).toHaveBeenCalledTimes(1); expect(databaseMock.runMigrations).not.toHaveBeenCalled(); }); - it.each([{ major: 14 }, { major: 15 }, { major: 16 }])( - `should suggest image with postgres $major if database is $major`, - async ({ major }) => { - databaseMock.getExtensionVersion.mockResolvedValue(new Version(0, 0, 1)); - databaseMock.getPostgresVersion.mockResolvedValue(new Version(major, 0, 0)); + it(`should update ${extName} if a newer version is available`, async () => { + const version = new Version(minVersion.major, minVersion.minor + 1, minVersion.patch); + databaseMock.getAvailableExtensionVersion.mockResolvedValue(version); - await expect(sut.init()).rejects.toThrow(new RegExp(`tensorchord\/pgvecto-rs:pg${major}-v0\\.1\\.11`, 's')); + await expect(sut.init()).resolves.toBeUndefined(); + + expect(databaseMock.updateVectorExtension).toHaveBeenCalledWith(vectorExt, version); + expect(databaseMock.updateVectorExtension).toHaveBeenCalledTimes(1); + expect(databaseMock.runMigrations).toHaveBeenCalledTimes(1); + expect(fatalLog).not.toHaveBeenCalled(); + }); + + it(`should not update ${extName} if a newer version is higher than the maximum`, async () => { + const version = new Version(minVersion.major + 1, minVersion.minor, minVersion.patch); + databaseMock.getAvailableExtensionVersion.mockResolvedValue(version); + + await expect(sut.init()).resolves.toBeUndefined(); + + expect(databaseMock.updateVectorExtension).not.toHaveBeenCalled(); + expect(databaseMock.runMigrations).toHaveBeenCalledTimes(1); + expect(fatalLog).not.toHaveBeenCalled(); + }); + + it(`should warn if attempted to update ${extName} and failed`, async () => { + const version = new Version(minVersion.major, minVersion.minor, minVersion.patch + 1); + databaseMock.getAvailableExtensionVersion.mockResolvedValue(version); + databaseMock.updateVectorExtension.mockRejectedValue(new Error('Failed to update extension')); + + await expect(sut.init()).resolves.toBeUndefined(); + + expect(warnLog).toHaveBeenCalledTimes(1); + expect(warnLog.mock.calls[0][0]).toContain(extName); + expect(errorLog).toHaveBeenCalledTimes(1); + expect(fatalLog).not.toHaveBeenCalled(); + expect(databaseMock.updateVectorExtension).toHaveBeenCalledWith(vectorExt, version); + expect(databaseMock.runMigrations).toHaveBeenCalledTimes(1); + }); + + it(`should warn if ${extName} update requires restart`, async () => { + const version = new Version(minVersion.major, minVersion.minor, minVersion.patch + 1); + databaseMock.getAvailableExtensionVersion.mockResolvedValue(version); + databaseMock.updateVectorExtension.mockResolvedValue({ restartRequired: true }); + + await expect(sut.init()).resolves.toBeUndefined(); + + expect(warnLog).toHaveBeenCalledTimes(1); + expect(warnLog.mock.calls[0][0]).toContain(extName); + expect(databaseMock.updateVectorExtension).toHaveBeenCalledWith(vectorExt, version); + expect(databaseMock.runMigrations).toHaveBeenCalledTimes(1); + expect(fatalLog).not.toHaveBeenCalled(); + }); + + it.each([{ index: VectorIndex.CLIP }, { index: VectorIndex.FACE }])( + `should reindex $index if necessary`, + async ({ index }) => { + databaseMock.shouldReindex.mockImplementation((indexArg) => Promise.resolve(indexArg === index)); + + await expect(sut.init()).resolves.toBeUndefined(); + + expect(databaseMock.shouldReindex).toHaveBeenCalledWith(index); + expect(databaseMock.shouldReindex).toHaveBeenCalledTimes(2); + expect(databaseMock.reindex).toHaveBeenCalledWith(index); + expect(databaseMock.reindex).toHaveBeenCalledTimes(1); + expect(databaseMock.runMigrations).toHaveBeenCalledTimes(1); + expect(fatalLog).not.toHaveBeenCalled(); }, ); - it('should not suggest image if postgres version is not in 14, 15 or 16', async () => { - databaseMock.getPostgresVersion.mockResolvedValueOnce(new Version(17, 0, 0)); - databaseMock.getPostgresVersion.mockResolvedValueOnce(new Version(17, 0, 0)); + it.each([{ index: VectorIndex.CLIP }, { index: VectorIndex.FACE }])( + `should not reindex $index if not necessary`, + async () => { + databaseMock.shouldReindex.mockResolvedValue(false); - await expect(sut.init()).rejects.toThrow(/^(?:(?!tensorchord\/pgvecto-rs).)*$/s); - }); + await expect(sut.init()).resolves.toBeUndefined(); - it('should reject and suggest the maximum supported version when unsupported pgvecto.rs version is in use', async () => { - databaseMock.getExtensionVersion.mockResolvedValue(new Version(0, 0, 1)); - - await expect(sut.init()).rejects.toThrow(/('tensorchord\/pgvecto-rs:pg14-v0\.1\.11')/s); - - sut.maxVectorsVersion = new Version(0, 1, 12); - await expect(sut.init()).rejects.toThrow(/('tensorchord\/pgvecto-rs:pg14-v0\.1\.12')/s); - }); + expect(databaseMock.shouldReindex).toHaveBeenCalledTimes(2); + expect(databaseMock.reindex).not.toHaveBeenCalled(); + expect(databaseMock.runMigrations).toHaveBeenCalledTimes(1); + expect(fatalLog).not.toHaveBeenCalled(); + }, + ); }); }); diff --git a/server/src/domain/database/database.service.ts b/server/src/domain/database/database.service.ts index 5af576a73b..5ea9e1a474 100644 --- a/server/src/domain/database/database.service.ts +++ b/server/src/domain/database/database.service.ts @@ -1,74 +1,56 @@ import { ImmichLogger } from '@app/infra/logger'; import { Inject, Injectable } from '@nestjs/common'; import { QueryFailedError } from 'typeorm'; -import { Version } from '../domain.constant'; -import { DatabaseExtension, IDatabaseRepository } from '../repositories'; +import { Version, VersionType } from '../domain.constant'; +import { + DatabaseExtension, + DatabaseLock, + IDatabaseRepository, + VectorExtension, + VectorIndex, + extName, +} from '../repositories'; @Injectable() export class DatabaseService { private logger = new ImmichLogger(DatabaseService.name); + private vectorExt: VectorExtension; minPostgresVersion = 14; - minVectorsVersion = new Version(0, 1, 1); - maxVectorsVersion = new Version(0, 1, 11); + minVectorsVersion = new Version(0, 2, 0); + vectorsVersionPin = VersionType.MINOR; + minVectorVersion = new Version(0, 5, 0); + vectorVersionPin = VersionType.MAJOR; - constructor(@Inject(IDatabaseRepository) private databaseRepository: IDatabaseRepository) {} + constructor(@Inject(IDatabaseRepository) private databaseRepository: IDatabaseRepository) { + this.vectorExt = this.databaseRepository.getPreferredVectorExtension(); + } async init() { await this.assertPostgresql(); - await this.createVectors(); - await this.assertVectors(); - await this.databaseRepository.runMigrations(); - } + await this.databaseRepository.withLock(DatabaseLock.Migrations, async () => { + await this.createVectorExtension(); + await this.updateVectorExtension(); + await this.assertVectorExtension(); - private async assertVectors() { - const version = await this.databaseRepository.getExtensionVersion(DatabaseExtension.VECTORS); - if (version == null) { - throw new Error('Unexpected: The pgvecto.rs extension is not installed.'); - } + try { + if (await this.databaseRepository.shouldReindex(VectorIndex.CLIP)) { + await this.databaseRepository.reindex(VectorIndex.CLIP); + } - const image = await this.getVectorsImage(); - const suggestion = image ? `, such as with the docker image '${image}'` : ''; + if (await this.databaseRepository.shouldReindex(VectorIndex.FACE)) { + await this.databaseRepository.reindex(VectorIndex.FACE); + } + } catch (error) { + this.logger.warn( + 'Could not run vector reindexing checks. If the extension was updated, please restart the Postgres instance.', + ); + throw error; + } - if (version.isEqual(new Version(0, 0, 0))) { - throw new Error( - `The pgvecto.rs extension version is ${version}, which means it is a nightly release.` + - `Please run 'DROP EXTENSION IF EXISTS vectors' and switch to a release version${suggestion}.`, - ); - } - - if (version.isNewerThan(this.maxVectorsVersion)) { - throw new Error(` - The pgvecto.rs extension version is ${version} instead of ${this.maxVectorsVersion}. - Please run 'DROP EXTENSION IF EXISTS vectors' and switch to ${this.maxVectorsVersion}${suggestion}.`); - } - - if (version.isOlderThan(this.minVectorsVersion)) { - throw new Error(` - The pgvecto.rs extension version is ${version}, which is older than the minimum supported version ${this.minVectorsVersion}. - Please upgrade to this version or later${suggestion}.`); - } - } - - private async createVectors() { - await this.databaseRepository.createExtension(DatabaseExtension.VECTORS).catch(async (error: QueryFailedError) => { - const image = await this.getVectorsImage(); - this.logger.fatal(` - Failed to create pgvecto.rs extension. - If you have not updated your Postgres instance to a docker image that supports pgvecto.rs (such as '${image}'), please do so. - See the v1.91.0 release notes for more info: https://github.com/immich-app/immich/releases/tag/v1.91.0' - `); - throw error; + await this.databaseRepository.runMigrations(); }); } - private async getVectorsImage() { - const { major } = await this.databaseRepository.getPostgresVersion(); - if (![14, 15, 16].includes(major)) { - return null; - } - return `tensorchord/pgvecto-rs:pg${major}-v${this.maxVectorsVersion}`; - } - private async assertPostgresql() { const { major } = await this.databaseRepository.getPostgresVersion(); if (major < this.minPostgresVersion) { @@ -77,4 +59,99 @@ export class DatabaseService { Please upgrade to this version or later.`); } } + + private async createVectorExtension() { + await this.databaseRepository.createExtension(this.vectorExt).catch(async (error: QueryFailedError) => { + const otherExt = + this.vectorExt === DatabaseExtension.VECTORS ? DatabaseExtension.VECTOR : DatabaseExtension.VECTORS; + this.logger.fatal(` + Failed to activate ${extName[this.vectorExt]} extension. + Please ensure the Postgres instance has ${extName[this.vectorExt]} installed. + + If the Postgres instance already has ${extName[this.vectorExt]} installed, Immich may not have the necessary permissions to activate it. + In this case, please run 'CREATE EXTENSION IF NOT EXISTS ${this.vectorExt}' manually as a superuser. + See https://immich.app/docs/guides/database-queries for how to query the database. + + Alternatively, if your Postgres instance has ${extName[otherExt]}, you may use this instead by setting the environment variable 'VECTOR_EXTENSION=${otherExt}'. + Note that switching between the two extensions after a successful startup is not supported. + The exception is if your version of Immich prior to upgrading was 1.90.2 or earlier. + In this case, you may set either extension now, but you will not be able to switch to the other extension following a successful startup. + `); + throw error; + }); + } + + private async updateVectorExtension() { + const [version, availableVersion] = await Promise.all([ + this.databaseRepository.getExtensionVersion(this.vectorExt), + this.databaseRepository.getAvailableExtensionVersion(this.vectorExt), + ]); + if (version == null) { + throw new Error(`Unexpected: ${extName[this.vectorExt]} extension is not installed.`); + } + + if (availableVersion == null) { + return; + } + + const maxVersion = this.vectorExt === DatabaseExtension.VECTOR ? this.vectorVersionPin : this.vectorsVersionPin; + const isNewer = availableVersion.isNewerThan(version); + if (isNewer == null || isNewer > maxVersion) { + return; + } + + try { + this.logger.log(`Updating ${extName[this.vectorExt]} extension to ${availableVersion}`); + const { restartRequired } = await this.databaseRepository.updateVectorExtension(this.vectorExt, availableVersion); + if (restartRequired) { + this.logger.warn(` + The ${extName[this.vectorExt]} extension has been updated to ${availableVersion}. + Please restart the Postgres instance to complete the update.`); + } + } catch (error) { + this.logger.warn(` + The ${extName[this.vectorExt]} extension version is ${version}, but ${availableVersion} is available. + Immich attempted to update the extension, but failed to do so. + This may be because Immich does not have the necessary permissions to update the extension. + + Please run 'ALTER EXTENSION ${this.vectorExt} UPDATE' manually as a superuser. + See https://immich.app/docs/guides/database-queries for how to query the database.`); + this.logger.error(error); + } + } + + private async assertVectorExtension() { + const version = await this.databaseRepository.getExtensionVersion(this.vectorExt); + if (version == null) { + throw new Error(`Unexpected: The ${extName[this.vectorExt]} extension is not installed.`); + } + + if (version.isEqual(new Version(0, 0, 0))) { + throw new Error(` + The ${extName[this.vectorExt]} extension version is ${version}, which means it is a nightly release. + + Please run 'DROP EXTENSION IF EXISTS ${this.vectorExt}' and switch to a release version. + See https://immich.app/docs/guides/database-queries for how to query the database.`); + } + + const minVersion = this.vectorExt === DatabaseExtension.VECTOR ? this.minVectorVersion : this.minVectorsVersion; + const maxVersion = this.vectorExt === DatabaseExtension.VECTOR ? this.vectorVersionPin : this.vectorsVersionPin; + + if (version.isOlderThan(minVersion) || version.isNewerThan(minVersion) > maxVersion) { + const allowedReleaseType = maxVersion === VersionType.MAJOR ? '' : ` ${VersionType[maxVersion].toLowerCase()}`; + const releases = + maxVersion === VersionType.EQUAL + ? minVersion.toString() + : `${minVersion} and later${allowedReleaseType} releases`; + + throw new Error(` + The ${extName[this.vectorExt]} extension version is ${version}, but Immich only supports ${releases}. + + If the Postgres instance already has a compatible version installed, Immich may not have the necessary permissions to activate it. + In this case, please run 'ALTER EXTENSION UPDATE ${this.vectorExt}' manually as a superuser. + See https://immich.app/docs/guides/database-queries for how to query the database. + + Otherwise, please update the version of ${extName[this.vectorExt]} in the Postgres instance to a compatible version.`); + } + } } diff --git a/server/src/domain/domain.config.ts b/server/src/domain/domain.config.ts index 3a106bad2b..ed1283ec2f 100644 --- a/server/src/domain/domain.config.ts +++ b/server/src/domain/domain.config.ts @@ -24,5 +24,6 @@ export const immichAppConfig: ConfigModuleOptions = { MACHINE_LEARNING_PORT: Joi.number().optional(), MICROSERVICES_PORT: Joi.number().optional(), SERVER_PORT: Joi.number().optional(), + VECTOR_EXTENSION: Joi.string().optional().valid('pgvector', 'pgvecto.rs').default('pgvecto.rs'), }), }; diff --git a/server/src/domain/domain.constant.spec.ts b/server/src/domain/domain.constant.spec.ts index 4ec4b1124c..154128a1c2 100644 --- a/server/src/domain/domain.constant.spec.ts +++ b/server/src/domain/domain.constant.spec.ts @@ -1,4 +1,4 @@ -import { Version, mimeTypes } from './domain.constant'; +import { Version, VersionType, mimeTypes } from './domain.constant'; describe('mimeTypes', () => { for (const { mimetype, extension } of [ @@ -196,45 +196,37 @@ describe('mimeTypes', () => { }); }); -describe('ServerVersion', () => { +describe('Version', () => { const tests = [ - { this: new Version(0, 0, 1), other: new Version(0, 0, 0), expected: 1 }, - { this: new Version(0, 1, 0), other: new Version(0, 0, 0), expected: 1 }, - { this: new Version(1, 0, 0), other: new Version(0, 0, 0), expected: 1 }, - { this: new Version(0, 0, 0), other: new Version(0, 0, 1), expected: -1 }, - { this: new Version(0, 0, 0), other: new Version(0, 1, 0), expected: -1 }, - { this: new Version(0, 0, 0), other: new Version(1, 0, 0), expected: -1 }, - { this: new Version(0, 0, 0), other: new Version(0, 0, 0), expected: 0 }, - { this: new Version(0, 0, 1), other: new Version(0, 0, 1), expected: 0 }, - { this: new Version(0, 1, 0), other: new Version(0, 1, 0), expected: 0 }, - { this: new Version(1, 0, 0), other: new Version(1, 0, 0), expected: 0 }, - { this: new Version(1, 0), other: new Version(1, 0, 0), expected: 0 }, - { this: new Version(1, 0), other: new Version(1, 0, 1), expected: -1 }, - { this: new Version(1, 1), other: new Version(1, 0, 1), expected: 1 }, - { this: new Version(1), other: new Version(1, 0, 0), expected: 0 }, - { this: new Version(1), other: new Version(1, 0, 1), expected: -1 }, + { this: new Version(0, 0, 1), other: new Version(0, 0, 0), compare: 1, type: VersionType.PATCH }, + { this: new Version(0, 1, 0), other: new Version(0, 0, 0), compare: 1, type: VersionType.MINOR }, + { this: new Version(1, 0, 0), other: new Version(0, 0, 0), compare: 1, type: VersionType.MAJOR }, + { this: new Version(0, 0, 0), other: new Version(0, 0, 1), compare: -1, type: VersionType.PATCH }, + { this: new Version(0, 0, 0), other: new Version(0, 1, 0), compare: -1, type: VersionType.MINOR }, + { this: new Version(0, 0, 0), other: new Version(1, 0, 0), compare: -1, type: VersionType.MAJOR }, + { this: new Version(0, 0, 0), other: new Version(0, 0, 0), compare: 0, type: VersionType.EQUAL }, + { this: new Version(0, 0, 1), other: new Version(0, 0, 1), compare: 0, type: VersionType.EQUAL }, + { this: new Version(0, 1, 0), other: new Version(0, 1, 0), compare: 0, type: VersionType.EQUAL }, + { this: new Version(1, 0, 0), other: new Version(1, 0, 0), compare: 0, type: VersionType.EQUAL }, + { this: new Version(1, 0), other: new Version(1, 0, 0), compare: 0, type: VersionType.EQUAL }, + { this: new Version(1, 0), other: new Version(1, 0, 1), compare: -1, type: VersionType.PATCH }, + { this: new Version(1, 1), other: new Version(1, 0, 1), compare: 1, type: VersionType.MINOR }, + { this: new Version(1), other: new Version(1, 0, 0), compare: 0, type: VersionType.EQUAL }, + { this: new Version(1), other: new Version(1, 0, 1), compare: -1, type: VersionType.PATCH }, ]; - describe('compare', () => { - for (const { this: thisVersion, other: otherVersion, expected } of tests) { - it(`should return ${expected} when comparing ${thisVersion} to ${otherVersion}`, () => { - expect(thisVersion.compare(otherVersion)).toEqual(expected); - }); - } - }); - describe('isOlderThan', () => { - for (const { this: thisVersion, other: otherVersion, expected } of tests) { - const bool = expected < 0; - it(`should return ${bool} when comparing ${thisVersion} to ${otherVersion}`, () => { - expect(thisVersion.isOlderThan(otherVersion)).toEqual(bool); + for (const { this: thisVersion, other: otherVersion, compare, type } of tests) { + const expected = compare < 0 ? type : VersionType.EQUAL; + it(`should return '${expected}' when comparing ${thisVersion} to ${otherVersion}`, () => { + expect(thisVersion.isOlderThan(otherVersion)).toEqual(expected); }); } }); describe('isEqual', () => { - for (const { this: thisVersion, other: otherVersion, expected } of tests) { - const bool = expected === 0; + for (const { this: thisVersion, other: otherVersion, compare } of tests) { + const bool = compare === 0; it(`should return ${bool} when comparing ${thisVersion} to ${otherVersion}`, () => { expect(thisVersion.isEqual(otherVersion)).toEqual(bool); }); @@ -242,10 +234,10 @@ describe('ServerVersion', () => { }); describe('isNewerThan', () => { - for (const { this: thisVersion, other: otherVersion, expected } of tests) { - const bool = expected > 0; - it(`should return ${bool} when comparing ${thisVersion} to ${otherVersion}`, () => { - expect(thisVersion.isNewerThan(otherVersion)).toEqual(bool); + for (const { this: thisVersion, other: otherVersion, compare, type } of tests) { + const expected = compare > 0 ? type : VersionType.EQUAL; + it(`should return ${expected} when comparing ${thisVersion} to ${otherVersion}`, () => { + expect(thisVersion.isNewerThan(otherVersion)).toEqual(expected); }); } }); diff --git a/server/src/domain/domain.constant.ts b/server/src/domain/domain.constant.ts index 227595e04f..4e7c4d5524 100644 --- a/server/src/domain/domain.constant.ts +++ b/server/src/domain/domain.constant.ts @@ -12,11 +12,20 @@ export interface IVersion { patch: number; } +export enum VersionType { + EQUAL = 0, + PATCH = 1, + MINOR = 2, + MAJOR = 3, +} + export class Version implements IVersion { + public readonly types = ['major', 'minor', 'patch'] as const; + constructor( - public readonly major: number, - public readonly minor: number = 0, - public readonly patch: number = 0, + public major: number, + public minor: number = 0, + public patch: number = 0, ) {} toString() { @@ -39,27 +48,30 @@ export class Version implements IVersion { } } - compare(version: Version): number { - for (const key of ['major', 'minor', 'patch'] as const) { + private compare(version: Version): [number, VersionType] { + for (const [i, key] of this.types.entries()) { const diff = this[key] - version[key]; if (diff !== 0) { - return diff > 0 ? 1 : -1; + return [diff > 0 ? 1 : -1, (VersionType.MAJOR - i) as VersionType]; } } - return 0; + return [0, VersionType.EQUAL]; } - isOlderThan(version: Version): boolean { - return this.compare(version) < 0; + isOlderThan(version: Version): VersionType { + const [bool, type] = this.compare(version); + return bool < 0 ? type : VersionType.EQUAL; } isEqual(version: Version): boolean { - return this.compare(version) === 0; + const [bool] = this.compare(version); + return bool === 0; } - isNewerThan(version: Version): boolean { - return this.compare(version) > 0; + isNewerThan(version: Version): VersionType { + const [bool, type] = this.compare(version); + return bool > 0 ? type : VersionType.EQUAL; } } diff --git a/server/src/domain/repositories/database.repository.ts b/server/src/domain/repositories/database.repository.ts index 07d0afca6b..d32939fe61 100644 --- a/server/src/domain/repositories/database.repository.ts +++ b/server/src/domain/repositories/database.repository.ts @@ -3,21 +3,47 @@ import { Version } from '../domain.constant'; export enum DatabaseExtension { CUBE = 'cube', EARTH_DISTANCE = 'earthdistance', + VECTOR = 'vector', VECTORS = 'vectors', } +export type VectorExtension = DatabaseExtension.VECTOR | DatabaseExtension.VECTORS; + +export enum VectorIndex { + CLIP = 'clip_index', + FACE = 'face_index', +} + export enum DatabaseLock { GeodataImport = 100, + Migrations = 200, StorageTemplateMigration = 420, CLIPDimSize = 512, } +export const extName: Record = { + cube: 'cube', + earthdistance: 'earthdistance', + vector: 'pgvector', + vectors: 'pgvecto.rs', +} as const; + +export interface VectorUpdateResult { + restartRequired: boolean; +} + export const IDatabaseRepository = 'IDatabaseRepository'; export interface IDatabaseRepository { getExtensionVersion(extensionName: string): Promise; + getAvailableExtensionVersion(extension: DatabaseExtension): Promise; + getPreferredVectorExtension(): VectorExtension; getPostgresVersion(): Promise; createExtension(extension: DatabaseExtension): Promise; + updateExtension(extension: DatabaseExtension, version?: Version): Promise; + updateVectorExtension(extension: VectorExtension, version?: Version): Promise; + reindex(index: VectorIndex): Promise; + shouldReindex(name: VectorIndex): Promise; runMigrations(options?: { transaction?: 'all' | 'none' | 'each' }): Promise; withLock(lock: DatabaseLock, callback: () => Promise): Promise; isBusy(lock: DatabaseLock): boolean; diff --git a/server/src/domain/repositories/smart-info.repository.ts b/server/src/domain/repositories/smart-info.repository.ts index 7b82e9d744..acb907bc8f 100644 --- a/server/src/domain/repositories/smart-info.repository.ts +++ b/server/src/domain/repositories/smart-info.repository.ts @@ -7,7 +7,7 @@ export type Embedding = number[]; export interface EmbeddingSearch { userIds: string[]; embedding: Embedding; - numResults?: number; + numResults: number; withArchived?: boolean; } diff --git a/server/src/infra/database.config.ts b/server/src/infra/database.config.ts index 9e6cccd198..93926e51cf 100644 --- a/server/src/infra/database.config.ts +++ b/server/src/infra/database.config.ts @@ -1,3 +1,4 @@ +import { DatabaseExtension } from '@app/domain/repositories/database.repository'; import { DataSource } from 'typeorm'; import { PostgresConnectionOptions } from 'typeorm/driver/postgres/PostgresConnectionOptions.js'; @@ -27,3 +28,6 @@ export const databaseConfig: PostgresConnectionOptions = { // this export is used by TypeORM commands in package.json#scripts export const dataSource = new DataSource(databaseConfig); + +export const vectorExt = + process.env.VECTOR_EXTENSION === 'pgvector' ? DatabaseExtension.VECTOR : DatabaseExtension.VECTORS; diff --git a/server/src/infra/logger.ts b/server/src/infra/logger.ts index 183ffb492f..8de149c409 100644 --- a/server/src/infra/logger.ts +++ b/server/src/infra/logger.ts @@ -5,7 +5,7 @@ import { LogLevel } from './entities'; const LOG_LEVELS = [LogLevel.VERBOSE, LogLevel.DEBUG, LogLevel.LOG, LogLevel.WARN, LogLevel.ERROR, LogLevel.FATAL]; export class ImmichLogger extends ConsoleLogger { - private static logLevels: LogLevel[] = [LogLevel.WARN, LogLevel.ERROR, LogLevel.FATAL]; + private static logLevels: LogLevel[] = [LogLevel.LOG, LogLevel.WARN, LogLevel.ERROR, LogLevel.FATAL]; constructor(context: string) { super(context); diff --git a/server/src/infra/migrations/1700713871511-UsePgVectors.ts b/server/src/infra/migrations/1700713871511-UsePgVectors.ts index a952f1646d..008d5eadc8 100644 --- a/server/src/infra/migrations/1700713871511-UsePgVectors.ts +++ b/server/src/infra/migrations/1700713871511-UsePgVectors.ts @@ -1,11 +1,13 @@ import { getCLIPModelInfo } from '@app/domain/smart-info/smart-info.constant'; import { MigrationInterface, QueryRunner } from 'typeorm'; +import { vectorExt } from '@app/infra/database.config'; export class UsePgVectors1700713871511 implements MigrationInterface { name = 'UsePgVectors1700713871511'; public async up(queryRunner: QueryRunner): Promise { - await queryRunner.query(`CREATE EXTENSION IF NOT EXISTS vectors`); + await queryRunner.query(`SET search_path TO "$user", public, vectors`); + await queryRunner.query(`CREATE EXTENSION IF NOT EXISTS ${vectorExt}`); const faceDimQuery = await queryRunner.query(` SELECT CARDINALITY(embedding::real[]) as dimsize FROM asset_faces diff --git a/server/src/infra/migrations/1700713994428-AddCLIPEmbeddingIndex.ts b/server/src/infra/migrations/1700713994428-AddCLIPEmbeddingIndex.ts index 7a1a1144d6..c3716cc191 100644 --- a/server/src/infra/migrations/1700713994428-AddCLIPEmbeddingIndex.ts +++ b/server/src/infra/migrations/1700713994428-AddCLIPEmbeddingIndex.ts @@ -1,16 +1,20 @@ import { MigrationInterface, QueryRunner } from 'typeorm'; +import { vectorExt } from '../database.config'; +import { DatabaseExtension } from '@app/domain/repositories/database.repository'; export class AddCLIPEmbeddingIndex1700713994428 implements MigrationInterface { name = 'AddCLIPEmbeddingIndex1700713994428'; public async up(queryRunner: QueryRunner): Promise { + if (vectorExt === DatabaseExtension.VECTORS) { + await queryRunner.query(`SET vectors.pgvector_compatibility=on`); + } + await queryRunner.query(`SET search_path TO "$user", public, vectors`); + await queryRunner.query(` CREATE INDEX IF NOT EXISTS clip_index ON smart_search - USING vectors (embedding cosine_ops) WITH (options = $$ - [indexing.hnsw] - m = 16 - ef_construction = 300 - $$);`); + USING hnsw (embedding vector_cosine_ops) + WITH (ef_construction = 300, m = 16)`); } public async down(queryRunner: QueryRunner): Promise { diff --git a/server/src/infra/migrations/1700714033632-AddFaceEmbeddingIndex.ts b/server/src/infra/migrations/1700714033632-AddFaceEmbeddingIndex.ts index 0ac7b0cd4c..066303530a 100644 --- a/server/src/infra/migrations/1700714033632-AddFaceEmbeddingIndex.ts +++ b/server/src/infra/migrations/1700714033632-AddFaceEmbeddingIndex.ts @@ -1,16 +1,20 @@ import { MigrationInterface, QueryRunner } from 'typeorm'; +import { vectorExt } from '../database.config'; +import { DatabaseExtension } from '@app/domain/repositories/database.repository'; export class AddFaceEmbeddingIndex1700714033632 implements MigrationInterface { name = 'AddFaceEmbeddingIndex1700714033632'; public async up(queryRunner: QueryRunner): Promise { + if (vectorExt === DatabaseExtension.VECTORS) { + await queryRunner.query(`SET vectors.pgvector_compatibility=on`); + } + await queryRunner.query(`SET search_path TO "$user", public, vectors`); + await queryRunner.query(` CREATE INDEX IF NOT EXISTS face_index ON asset_faces - USING vectors (embedding cosine_ops) WITH (options = $$ - [indexing.hnsw] - m = 16 - ef_construction = 300 - $$);`); + USING hnsw (embedding vector_cosine_ops) + WITH (ef_construction = 300, m = 16)`); } public async down(queryRunner: QueryRunner): Promise { diff --git a/server/src/infra/migrations/1707000751533-AddVectorsToSearchPath.ts b/server/src/infra/migrations/1707000751533-AddVectorsToSearchPath.ts new file mode 100644 index 0000000000..e83e4b4fb0 --- /dev/null +++ b/server/src/infra/migrations/1707000751533-AddVectorsToSearchPath.ts @@ -0,0 +1,14 @@ +import { MigrationInterface, QueryRunner } from 'typeorm'; + +export class AddVectorsToSearchPath1707000751533 implements MigrationInterface { + public async up(queryRunner: QueryRunner): Promise { + const res = await queryRunner.query(`SELECT current_database() as db`); + const databaseName = res[0]['db']; + await queryRunner.query(`ALTER DATABASE ${databaseName} SET search_path TO "$user", public, vectors`); + } + + public async down(queryRunner: QueryRunner): Promise { + const databaseName = await queryRunner.query(`SELECT current_database()`); + await queryRunner.query(`ALTER DATABASE ${databaseName} SET search_path TO "$user", public`); + } +} diff --git a/server/src/infra/repositories/database.repository.ts b/server/src/infra/repositories/database.repository.ts index af595057e2..b0e4623af5 100644 --- a/server/src/infra/repositories/database.repository.ts +++ b/server/src/infra/repositories/database.repository.ts @@ -1,21 +1,60 @@ -import { DatabaseExtension, DatabaseLock, IDatabaseRepository, Version } from '@app/domain'; +import { + DatabaseExtension, + DatabaseLock, + IDatabaseRepository, + VectorExtension, + VectorIndex, + VectorUpdateResult, + Version, + VersionType, + extName, +} from '@app/domain'; +import { vectorExt } from '@app/infra/database.config'; import { Injectable } from '@nestjs/common'; import { InjectDataSource } from '@nestjs/typeorm'; import AsyncLock from 'async-lock'; -import { DataSource, QueryRunner } from 'typeorm'; +import { DataSource, EntityManager, QueryRunner } from 'typeorm'; +import { isValidInteger } from '../infra.utils'; +import { ImmichLogger } from '../logger'; @Injectable() export class DatabaseRepository implements IDatabaseRepository { + private logger = new ImmichLogger(DatabaseRepository.name); readonly asyncLock = new AsyncLock(); constructor(@InjectDataSource() private dataSource: DataSource) {} async getExtensionVersion(extension: DatabaseExtension): Promise { const res = await this.dataSource.query(`SELECT extversion FROM pg_extension WHERE extname = $1`, [extension]); - const version = res[0]?.['extversion']; + const extVersion = res[0]?.['extversion']; + if (extVersion == null) { + return null; + } + + const version = Version.fromString(extVersion); + if (version.isEqual(new Version(0, 1, 1))) { + return new Version(0, 1, 11); + } + + return version; + } + + async getAvailableExtensionVersion(extension: DatabaseExtension): Promise { + const res = await this.dataSource.query( + ` + SELECT version FROM pg_available_extension_versions + WHERE name = $1 AND installed = false + ORDER BY version DESC`, + [extension], + ); + const version = res[0]?.['version']; return version == null ? null : Version.fromString(version); } + getPreferredVectorExtension(): VectorExtension { + return vectorExt; + } + async getPostgresVersion(): Promise { const res = await this.dataSource.query(`SHOW server_version`); return Version.fromString(res[0]['server_version']); @@ -25,6 +64,129 @@ export class DatabaseRepository implements IDatabaseRepository { await this.dataSource.query(`CREATE EXTENSION IF NOT EXISTS ${extension}`); } + async updateExtension(extension: DatabaseExtension, version?: Version): Promise { + await this.dataSource.query(`ALTER EXTENSION ${extension} UPDATE${version ? ` TO '${version}'` : ''}`); + } + + async updateVectorExtension(extension: VectorExtension, version?: Version): Promise { + const curVersion = await this.getExtensionVersion(extension); + if (!curVersion) { + throw new Error(`${extName[extension]} extension is not installed`); + } + + const minorOrMajor = version && curVersion.isOlderThan(version) >= VersionType.MINOR; + const isVectors = extension === DatabaseExtension.VECTORS; + let restartRequired = false; + await this.dataSource.manager.transaction(async (manager) => { + await this.setSearchPath(manager); + if (minorOrMajor && isVectors) { + await this.updateVectorsSchema(manager, curVersion); + } + + await manager.query(`ALTER EXTENSION ${extension} UPDATE${version ? ` TO '${version}'` : ''}`); + + if (!minorOrMajor) { + return; + } + + if (isVectors) { + await manager.query('SELECT pgvectors_upgrade()'); + restartRequired = true; + } else { + await this.reindex(VectorIndex.CLIP); + await this.reindex(VectorIndex.FACE); + } + }); + + return { restartRequired }; + } + + async reindex(index: VectorIndex): Promise { + try { + await this.dataSource.query(`REINDEX INDEX ${index}`); + } catch (error) { + if (vectorExt === DatabaseExtension.VECTORS) { + this.logger.warn(`Could not reindex index ${index}. Attempting to auto-fix.`); + const table = index === VectorIndex.CLIP ? 'smart_search' : 'asset_faces'; + const dimSize = await this.getDimSize(table); + await this.dataSource.manager.transaction(async (manager) => { + await this.setSearchPath(manager); + await manager.query(`DROP INDEX IF EXISTS ${index}`); + await manager.query(`ALTER TABLE ${table} ALTER COLUMN embedding SET DATA TYPE real[]`); + await manager.query(`ALTER TABLE ${table} ALTER COLUMN embedding SET DATA TYPE vector(${dimSize})`); + await manager.query(`SET vectors.pgvector_compatibility=on`); + await manager.query(` + CREATE INDEX IF NOT EXISTS ${index} ON ${table} + USING hnsw (embedding vector_cosine_ops) + WITH (ef_construction = 300, m = 16)`); + }); + } else { + throw error; + } + } + } + + async shouldReindex(name: VectorIndex): Promise { + if (vectorExt !== DatabaseExtension.VECTORS) { + return false; + } + + try { + const res = await this.dataSource.query( + ` + SELECT idx_status + FROM pg_vector_index_stat + WHERE indexname = $1`, + [name], + ); + return res[0]?.['idx_status'] === 'UPGRADE'; + } catch (error) { + const message: string = (error as any).message; + if (message.includes('index is not existing')) { + return true; + } else if (message.includes('relation "pg_vector_index_stat" does not exist')) { + return false; + } + throw error; + } + } + + private async setSearchPath(manager: EntityManager): Promise { + await manager.query(`SET search_path TO "$user", public, vectors`); + } + + private async updateVectorsSchema(manager: EntityManager, curVersion: Version): Promise { + await manager.query('CREATE SCHEMA IF NOT EXISTS vectors'); + await manager.query(`UPDATE pg_catalog.pg_extension SET extversion = $1 WHERE extname = $2`, [ + curVersion.toString(), + DatabaseExtension.VECTORS, + ]); + await manager.query('UPDATE pg_catalog.pg_extension SET extrelocatable = true WHERE extname = $1', [ + DatabaseExtension.VECTORS, + ]); + await manager.query('ALTER EXTENSION vectors SET SCHEMA vectors'); + await manager.query('UPDATE pg_catalog.pg_extension SET extrelocatable = false WHERE extname = $1', [ + DatabaseExtension.VECTORS, + ]); + } + + private async getDimSize(table: string, column = 'embedding'): Promise { + const res = await this.dataSource.query(` + SELECT atttypmod as dimsize + FROM pg_attribute f + JOIN pg_class c ON c.oid = f.attrelid + WHERE c.relkind = 'r'::char + AND f.attnum > 0 + AND c.relname = '${table}' + AND f.attname = '${column}'`); + + const dimSize = res[0]['dimsize']; + if (!isValidInteger(dimSize, { min: 1, max: 2 ** 16 })) { + throw new Error(`Could not retrieve dimension size`); + } + return dimSize; + } + async runMigrations(options?: { transaction?: 'all' | 'none' | 'each' }): Promise { await this.dataSource.runMigrations(options); } diff --git a/server/src/infra/repositories/smart-info.repository.ts b/server/src/infra/repositories/smart-info.repository.ts index ab43ff6f91..f74fd4232d 100644 --- a/server/src/infra/repositories/smart-info.repository.ts +++ b/server/src/infra/repositories/smart-info.repository.ts @@ -1,10 +1,18 @@ -import { Embedding, EmbeddingSearch, FaceEmbeddingSearch, FaceSearchResult, ISmartInfoRepository } from '@app/domain'; +import { + DatabaseExtension, + Embedding, + EmbeddingSearch, + FaceEmbeddingSearch, + FaceSearchResult, + ISmartInfoRepository, +} from '@app/domain'; import { getCLIPModelInfo } from '@app/domain/smart-info/smart-info.constant'; import { AssetEntity, AssetFaceEntity, SmartInfoEntity, SmartSearchEntity } from '@app/infra/entities'; import { ImmichLogger } from '@app/infra/logger'; import { Injectable } from '@nestjs/common'; import { InjectRepository } from '@nestjs/typeorm'; import { Repository } from 'typeorm'; +import { vectorExt } from '../database.config'; import { DummyValue, GenerateSql } from '../infra.util'; import { asVector, isValidInteger } from '../infra.utils'; @@ -44,16 +52,20 @@ export class SmartInfoRepository implements ISmartInfoRepository { params: [{ userIds: [DummyValue.UUID], embedding: Array.from({ length: 512 }, Math.random), numResults: 100 }], }) async searchCLIP({ userIds, embedding, numResults, withArchived }: EmbeddingSearch): Promise { + if (!isValidInteger(numResults, { min: 1 })) { + throw new Error(`Invalid value for 'numResults': ${numResults}`); + } + + // setting this too low messes with prefilter recall + numResults = Math.max(numResults, 64); + let results: AssetEntity[] = []; await this.assetRepository.manager.transaction(async (manager) => { - await manager.query(`SET LOCAL vectors.enable_prefilter = on`); - - let query = manager + const query = manager .createQueryBuilder(AssetEntity, 'a') .innerJoin('a.smartSearch', 's') .leftJoinAndSelect('a.exifInfo', 'e') .where('a.ownerId IN (:...userIds )') - .orderBy('s.embedding <=> :embedding') .setParameters({ userIds, embedding: asVector(embedding) }); @@ -61,15 +73,9 @@ export class SmartInfoRepository implements ISmartInfoRepository { query.andWhere('a.isArchived = false'); } query.andWhere('a.isVisible = true').andWhere('a.fileCreatedAt < NOW()'); + query.limit(numResults); - if (numResults) { - if (!isValidInteger(numResults, { min: 1 })) { - throw new Error(`Invalid value for 'numResults': ${numResults}`); - } - query = query.limit(numResults); - await manager.query(`SET LOCAL vectors.k = '${numResults}'`); - } - + await manager.query(this.getRuntimeConfig(numResults)); results = await query.getMany(); }); @@ -93,36 +99,34 @@ export class SmartInfoRepository implements ISmartInfoRepository { maxDistance, hasPerson, }: FaceEmbeddingSearch): Promise { + if (!isValidInteger(numResults, { min: 1 })) { + throw new Error(`Invalid value for 'numResults': ${numResults}`); + } + + // setting this too low messes with prefilter recall + numResults = Math.max(numResults, 64); + let results: Array = []; await this.assetRepository.manager.transaction(async (manager) => { - await manager.query(`SET LOCAL vectors.enable_prefilter = on`); - let cte = manager + const cte = manager .createQueryBuilder(AssetFaceEntity, 'faces') - .select('1 + (faces.embedding <=> :embedding)', 'distance') + .select('faces.embedding <=> :embedding', 'distance') .innerJoin('faces.asset', 'asset') .where('asset.ownerId IN (:...userIds )') - .orderBy('1 + (faces.embedding <=> :embedding)') + .orderBy('faces.embedding <=> :embedding') .setParameters({ userIds, embedding: asVector(embedding) }); - if (numResults) { - if (!isValidInteger(numResults, { min: 1 })) { - throw new Error(`Invalid value for 'numResults': ${numResults}`); - } - cte = cte.limit(numResults); - if (numResults > 64) { - // setting k too low messes with prefilter recall - await manager.query(`SET LOCAL vectors.k = '${numResults}'`); - } - } + cte.limit(numResults); if (hasPerson) { - cte = cte.andWhere('faces."personId" IS NOT NULL'); + cte.andWhere('faces."personId" IS NOT NULL'); } for (const col of this.faceColumns) { cte.addSelect(`faces.${col}`, col); } + await manager.query(this.getRuntimeConfig(numResults)); results = await manager .createQueryBuilder() .select('res.*') @@ -167,6 +171,9 @@ export class SmartInfoRepository implements ISmartInfoRepository { this.logger.log(`Updating database CLIP dimension size to ${dimSize}.`); await this.smartSearchRepository.manager.transaction(async (manager) => { + if (vectorExt === DatabaseExtension.VECTORS) { + await manager.query(`SET vectors.pgvector_compatibility=on`); + } await manager.query(`DROP TABLE smart_search`); await manager.query(` @@ -175,12 +182,9 @@ export class SmartInfoRepository implements ISmartInfoRepository { embedding vector(${dimSize}) NOT NULL )`); await manager.query(` - CREATE INDEX clip_index ON smart_search - USING vectors (embedding cosine_ops) WITH (options = $$ - [indexing.hnsw] - m = 16 - ef_construction = 300 - $$)`); + CREATE INDEX IF NOT EXISTS clip_index ON smart_search + USING hnsw (embedding vector_cosine_ops) + WITH (ef_construction = 300, m = 16)`); }); this.logger.log(`Successfully updated database CLIP dimension size from ${currentDimSize} to ${dimSize}.`); @@ -202,4 +206,17 @@ export class SmartInfoRepository implements ISmartInfoRepository { } return dimSize; } + + private getRuntimeConfig(numResults?: number): string { + if (vectorExt === DatabaseExtension.VECTOR) { + return 'SET LOCAL hnsw.ef_search = 1000;'; // mitigate post-filter recall + } + + let runtimeConfig = 'SET LOCAL vectors.enable_prefilter=on; SET LOCAL vectors.search_mode=vbase;'; + if (numResults) { + runtimeConfig += ` SET LOCAL vectors.hnsw_ef_search = ${numResults};`; + } + + return runtimeConfig; + } } diff --git a/server/src/infra/sql/smart.info.repository.sql b/server/src/infra/sql/smart.info.repository.sql index afb120bade..3151aede73 100644 --- a/server/src/infra/sql/smart.info.repository.sql +++ b/server/src/infra/sql/smart.info.repository.sql @@ -3,9 +3,13 @@ -- SmartInfoRepository.searchCLIP START TRANSACTION SET - LOCAL vectors.enable_prefilter = on + LOCAL vectors.enable_prefilter = on; + SET - LOCAL vectors.k = '100' + LOCAL vectors.search_mode = vbase; + +SET + LOCAL vectors.hnsw_ef_search = 100; SELECT "a"."id" AS "a_id", "a"."deviceAssetId" AS "a_deviceAssetId", @@ -85,9 +89,13 @@ COMMIT -- SmartInfoRepository.searchFaces START TRANSACTION SET - LOCAL vectors.enable_prefilter = on + LOCAL vectors.enable_prefilter = on; + SET - LOCAL vectors.k = '100' + LOCAL vectors.search_mode = vbase; + +SET + LOCAL vectors.hnsw_ef_search = 100; WITH "cte" AS ( SELECT @@ -100,7 +108,7 @@ WITH "faces"."boundingBoxY1" AS "boundingBoxY1", "faces"."boundingBoxX2" AS "boundingBoxX2", "faces"."boundingBoxY2" AS "boundingBoxY2", - 1 + ("faces"."embedding" <= > $1) AS "distance" + "faces"."embedding" <= > $1 AS "distance" FROM "asset_faces" "faces" INNER JOIN "assets" "asset" ON "asset"."id" = "faces"."assetId" @@ -108,7 +116,7 @@ WITH WHERE "asset"."ownerId" IN ($2) ORDER BY - 1 + ("faces"."embedding" <= > $1) ASC + "faces"."embedding" <= > $1 ASC LIMIT 100 ) diff --git a/server/test/repositories/database.repository.mock.ts b/server/test/repositories/database.repository.mock.ts index f34e6b06b5..f5a4d39a67 100644 --- a/server/test/repositories/database.repository.mock.ts +++ b/server/test/repositories/database.repository.mock.ts @@ -3,8 +3,14 @@ import { IDatabaseRepository, Version } from '@app/domain'; export const newDatabaseRepositoryMock = (): jest.Mocked => { return { getExtensionVersion: jest.fn(), + getAvailableExtensionVersion: jest.fn(), + getPreferredVectorExtension: jest.fn(), getPostgresVersion: jest.fn().mockResolvedValue(new Version(14, 0, 0)), createExtension: jest.fn().mockImplementation(() => Promise.resolve()), + updateExtension: jest.fn(), + updateVectorExtension: jest.fn(), + reindex: jest.fn(), + shouldReindex: jest.fn(), runMigrations: jest.fn(), withLock: jest.fn().mockImplementation((_, function_: () => Promise) => function_()), isBusy: jest.fn(), From 479fca8f0266fe4431a2a32adbbd239b65dfdd88 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 7 Feb 2024 02:51:22 +0000 Subject: [PATCH 032/104] chore(deps): pin tensorchord/pgvecto-rs docker tag to 9072418 (#6960) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- docker/docker-compose.dev.yml | 2 +- docker/docker-compose.prod.yml | 2 +- docker/docker-compose.yml | 2 +- server/e2e/docker-compose.server-e2e.yml | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/docker/docker-compose.dev.yml b/docker/docker-compose.dev.yml index e380be4965..188b8c1234 100644 --- a/docker/docker-compose.dev.yml +++ b/docker/docker-compose.dev.yml @@ -103,7 +103,7 @@ services: database: container_name: immich_postgres - image: tensorchord/pgvecto-rs:pg14-v0.2.0 + image: tensorchord/pgvecto-rs:pg14-v0.2.0@sha256:90724186f0a3517cf6914295b5ab410db9ce23190a2d9d0b9dd6463e3fa298f0 env_file: - .env environment: diff --git a/docker/docker-compose.prod.yml b/docker/docker-compose.prod.yml index 857aa31540..48a526c4c1 100644 --- a/docker/docker-compose.prod.yml +++ b/docker/docker-compose.prod.yml @@ -61,7 +61,7 @@ services: database: container_name: immich_postgres - image: tensorchord/pgvecto-rs:pg14-v0.2.0 + image: tensorchord/pgvecto-rs:pg14-v0.2.0@sha256:90724186f0a3517cf6914295b5ab410db9ce23190a2d9d0b9dd6463e3fa298f0 env_file: - .env environment: diff --git a/docker/docker-compose.yml b/docker/docker-compose.yml index a9d8e2b38c..c32018b1b0 100644 --- a/docker/docker-compose.yml +++ b/docker/docker-compose.yml @@ -65,7 +65,7 @@ services: database: container_name: immich_postgres - image: tensorchord/pgvecto-rs:pg14-v0.2.0 + image: tensorchord/pgvecto-rs:pg14-v0.2.0@sha256:90724186f0a3517cf6914295b5ab410db9ce23190a2d9d0b9dd6463e3fa298f0 env_file: - .env environment: diff --git a/server/e2e/docker-compose.server-e2e.yml b/server/e2e/docker-compose.server-e2e.yml index 708ae2ca34..abb76ef25d 100644 --- a/server/e2e/docker-compose.server-e2e.yml +++ b/server/e2e/docker-compose.server-e2e.yml @@ -21,7 +21,7 @@ services: - database database: - image: tensorchord/pgvecto-rs:pg14-v0.2.0 + image: tensorchord/pgvecto-rs:pg14-v0.2.0@sha256:90724186f0a3517cf6914295b5ab410db9ce23190a2d9d0b9dd6463e3fa298f0 command: -c fsync=off -c shared_preload_libraries=vectors.so environment: POSTGRES_PASSWORD: postgres From b31c7681ae97f07f2e10d18d613d4132d8a843ab Mon Sep 17 00:00:00 2001 From: Mert <101130780+mertalev@users.noreply.github.com> Date: Wed, 7 Feb 2024 10:56:39 -0500 Subject: [PATCH 033/104] feat(server): optimize face re-queueing (#6961) * do not defer faces with no matches * move comment --- .../src/domain/person/person.service.spec.ts | 31 ++++++++++++++++--- server/src/domain/person/person.service.ts | 10 ++++-- 2 files changed, 34 insertions(+), 7 deletions(-) diff --git a/server/src/domain/person/person.service.spec.ts b/server/src/domain/person/person.service.spec.ts index e1937524af..9d55abc8e6 100644 --- a/server/src/domain/person/person.service.spec.ts +++ b/server/src/domain/person/person.service.spec.ts @@ -866,11 +866,29 @@ describe(PersonService.name, () => { }); }); - it('should defer non-core faces to end of queue', async () => { + it('should not queue face with no matches', async () => { const faces = [{ face: faceStub.noPerson1, distance: 0 }] as FaceSearchResult[]; + smartInfoMock.searchFaces.mockResolvedValue(faces); + personMock.getFaceByIdWithAssets.mockResolvedValue(faceStub.noPerson1); + personMock.create.mockResolvedValue(personStub.withName); + + await sut.handleRecognizeFaces({ id: faceStub.noPerson1.id }); + + expect(jobMock.queue).not.toHaveBeenCalled(); + expect(smartInfoMock.searchFaces).toHaveBeenCalledTimes(1); + expect(personMock.create).not.toHaveBeenCalled(); + expect(personMock.reassignFaces).not.toHaveBeenCalled(); + }); + + it('should defer non-core faces to end of queue', async () => { + const faces = [ + { face: faceStub.noPerson1, distance: 0 }, + { face: faceStub.noPerson2, distance: 0.4 }, + ] as FaceSearchResult[]; + configMock.load.mockResolvedValue([ - { key: SystemConfigKey.MACHINE_LEARNING_FACIAL_RECOGNITION_MIN_FACES, value: 2 }, + { key: SystemConfigKey.MACHINE_LEARNING_FACIAL_RECOGNITION_MIN_FACES, value: 3 }, ]); smartInfoMock.searchFaces.mockResolvedValue(faces); personMock.getFaceByIdWithAssets.mockResolvedValue(faceStub.noPerson1); @@ -887,11 +905,14 @@ describe(PersonService.name, () => { expect(personMock.reassignFaces).not.toHaveBeenCalled(); }); - it('should not assign person to non-core face with no matching person', async () => { - const faces = [{ face: faceStub.noPerson1, distance: 0 }] as FaceSearchResult[]; + it('should not assign person to deferred non-core face with no matching person', async () => { + const faces = [ + { face: faceStub.noPerson1, distance: 0 }, + { face: faceStub.noPerson2, distance: 0.4 }, + ] as FaceSearchResult[]; configMock.load.mockResolvedValue([ - { key: SystemConfigKey.MACHINE_LEARNING_FACIAL_RECOGNITION_MIN_FACES, value: 2 }, + { key: SystemConfigKey.MACHINE_LEARNING_FACIAL_RECOGNITION_MIN_FACES, value: 3 }, ]); smartInfoMock.searchFaces.mockResolvedValueOnce(faces).mockResolvedValueOnce([]); personMock.getFaceByIdWithAssets.mockResolvedValue(faceStub.noPerson1); diff --git a/server/src/domain/person/person.service.ts b/server/src/domain/person/person.service.ts index 576f94c491..63fc350002 100644 --- a/server/src/domain/person/person.service.ts +++ b/server/src/domain/person/person.service.ts @@ -417,7 +417,13 @@ export class PersonService { numResults: machineLearning.facialRecognition.minFaces, }); - this.logger.debug(`Face ${id} has ${matches.length} match${matches.length == 1 ? '' : 'es'}`); + // `matches` also includes the face itself + if (matches.length <= 1) { + this.logger.debug(`Face ${id} has no matches`); + return true; + } + + this.logger.debug(`Face ${id} has ${matches.length} matches`); const isCore = matches.length >= machineLearning.facialRecognition.minFaces; if (!isCore && !deferred) { @@ -426,7 +432,7 @@ export class PersonService { return true; } - let personId = matches.find((match) => match.face.personId)?.face.personId; // `matches` also includes the face itself + let personId = matches.find((match) => match.face.personId)?.face.personId; if (!personId) { const matchWithPerson = await this.smartInfoRepository.searchFaces({ userIds: [face.asset.ownerId], From cab79c04d3f64858ca35b520b65feeed7f224e90 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 7 Feb 2024 11:57:36 -0500 Subject: [PATCH 034/104] chore(deps): bump stumpylog/image-cleaner-action from 0.4.0 to 0.5.0 (#6965) Bumps [stumpylog/image-cleaner-action](https://github.com/stumpylog/image-cleaner-action) from 0.4.0 to 0.5.0. - [Release notes](https://github.com/stumpylog/image-cleaner-action/releases) - [Changelog](https://github.com/stumpylog/image-cleaner-action/blob/main/CHANGELOG.md) - [Commits](https://github.com/stumpylog/image-cleaner-action/compare/v0.4.0...v0.5.0) --- updated-dependencies: - dependency-name: stumpylog/image-cleaner-action dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/docker-cleanup.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/docker-cleanup.yml b/.github/workflows/docker-cleanup.yml index a49ba55912..fd404e84ef 100644 --- a/.github/workflows/docker-cleanup.yml +++ b/.github/workflows/docker-cleanup.yml @@ -35,7 +35,7 @@ jobs: steps: - name: Clean temporary images if: "${{ env.TOKEN != '' }}" - uses: stumpylog/image-cleaner-action/ephemeral@v0.4.0 + uses: stumpylog/image-cleaner-action/ephemeral@v0.5.0 with: token: "${{ env.TOKEN }}" owner: "immich-app" @@ -64,7 +64,7 @@ jobs: steps: - name: Clean untagged images if: "${{ env.TOKEN != '' }}" - uses: stumpylog/image-cleaner-action/untagged@v0.4.0 + uses: stumpylog/image-cleaner-action/untagged@v0.5.0 with: token: "${{ env.TOKEN }}" owner: "immich-app" From 4ea15a5b0c05650e5bffad5fc129ec93c8f7c880 Mon Sep 17 00:00:00 2001 From: Jan <17313367+JW-CH@users.noreply.github.com> Date: Wed, 7 Feb 2024 18:30:38 +0100 Subject: [PATCH 035/104] fix(server): check if sidecarPath exists (#6293) * check if sidecarPath exists * Revert "check if sidecarPath exists" This reverts commit 954a1097b870585afee34974d466e51c5172fed9. * sidecar sync remove dead sidecarPaths and discover new ones * tests and minor cleanup * chore: linting --------- Co-authored-by: Daniel Dietzler Co-authored-by: Jason Rasmussen --- .../domain/metadata/metadata.service.spec.ts | 49 ++++++++++++++-- .../src/domain/metadata/metadata.service.ts | 57 ++++++++++++------- server/src/microservices/app.service.ts | 2 +- 3 files changed, 81 insertions(+), 27 deletions(-) diff --git a/server/src/domain/metadata/metadata.service.spec.ts b/server/src/domain/metadata/metadata.service.spec.ts index e27e5f2ee3..6eafc176bb 100644 --- a/server/src/domain/metadata/metadata.service.spec.ts +++ b/server/src/domain/metadata/metadata.service.spec.ts @@ -37,7 +37,6 @@ import { IStorageRepository, ISystemConfigRepository, ImmichTags, - WithProperty, WithoutProperty, } from '../repositories'; import { MetadataService, Orientation } from './metadata.service'; @@ -598,11 +597,11 @@ describe(MetadataService.name, () => { describe('handleQueueSidecar', () => { it('should queue assets with sidecar files', async () => { - assetMock.getWith.mockResolvedValue({ items: [assetStub.sidecar], hasNextPage: false }); + assetMock.getAll.mockResolvedValue({ items: [assetStub.sidecar], hasNextPage: false }); await sut.handleQueueSidecar({ force: true }); - expect(assetMock.getWith).toHaveBeenCalledWith({ take: 1000, skip: 0 }, WithProperty.SIDECAR); + expect(assetMock.getAll).toHaveBeenCalledWith({ take: 1000, skip: 0 }); expect(assetMock.getWithout).not.toHaveBeenCalled(); expect(jobMock.queueAll).toHaveBeenCalledWith([ { @@ -618,7 +617,7 @@ describe(MetadataService.name, () => { await sut.handleQueueSidecar({ force: false }); expect(assetMock.getWithout).toHaveBeenCalledWith({ take: 1000, skip: 0 }, WithoutProperty.SIDECAR); - expect(assetMock.getWith).not.toHaveBeenCalled(); + expect(assetMock.getAll).not.toHaveBeenCalled(); expect(jobMock.queueAll).toHaveBeenCalledWith([ { name: JobName.SIDECAR_DISCOVERY, @@ -629,8 +628,46 @@ describe(MetadataService.name, () => { }); describe('handleSidecarSync', () => { - it('should not error', async () => { - await sut.handleSidecarSync(); + it('should do nothing if asset could not be found', async () => { + assetMock.getByIds.mockResolvedValue([]); + await expect(sut.handleSidecarSync({ id: assetStub.image.id })).resolves.toBe(false); + expect(assetMock.save).not.toHaveBeenCalled(); + }); + + it('should do nothing if asset has no sidecar path', async () => { + assetMock.getByIds.mockResolvedValue([assetStub.image]); + await expect(sut.handleSidecarSync({ id: assetStub.image.id })).resolves.toBe(false); + expect(assetMock.save).not.toHaveBeenCalled(); + }); + + it('should do nothing if asset has no sidecar path', async () => { + assetMock.getByIds.mockResolvedValue([assetStub.image]); + await expect(sut.handleSidecarSync({ id: assetStub.image.id })).resolves.toBe(false); + expect(assetMock.save).not.toHaveBeenCalled(); + }); + + it('should set sidecar path if exists', async () => { + assetMock.getByIds.mockResolvedValue([assetStub.sidecar]); + storageMock.checkFileExists.mockResolvedValue(true); + + await expect(sut.handleSidecarSync({ id: assetStub.sidecar.id })).resolves.toBe(true); + expect(storageMock.checkFileExists).toHaveBeenCalledWith(`${assetStub.sidecar.originalPath}.xmp`, constants.R_OK); + expect(assetMock.save).toHaveBeenCalledWith({ + id: assetStub.sidecar.id, + sidecarPath: assetStub.sidecar.sidecarPath, + }); + }); + + it('should unset sidecar path if file does not exist anymore', async () => { + assetMock.getByIds.mockResolvedValue([assetStub.sidecar]); + storageMock.checkFileExists.mockResolvedValue(false); + + await expect(sut.handleSidecarSync({ id: assetStub.sidecar.id })).resolves.toBe(true); + expect(storageMock.checkFileExists).toHaveBeenCalledWith(`${assetStub.sidecar.originalPath}.xmp`, constants.R_OK); + expect(assetMock.save).toHaveBeenCalledWith({ + id: assetStub.sidecar.id, + sidecarPath: null, + }); }); }); diff --git a/server/src/domain/metadata/metadata.service.ts b/server/src/domain/metadata/metadata.service.ts index bcec1ac689..94c3e9ae3f 100644 --- a/server/src/domain/metadata/metadata.service.ts +++ b/server/src/domain/metadata/metadata.service.ts @@ -25,7 +25,6 @@ import { IStorageRepository, ISystemConfigRepository, ImmichTags, - WithProperty, WithoutProperty, } from '../repositories'; import { StorageCore } from '../storage'; @@ -267,7 +266,7 @@ export class MetadataService { const { force } = job; const assetPagination = usePagination(JOBS_ASSET_PAGINATION_SIZE, (pagination) => { return force - ? this.assetRepository.getWith(pagination, WithProperty.SIDECAR) + ? this.assetRepository.getAll(pagination) : this.assetRepository.getWithout(pagination, WithoutProperty.SIDECAR); }); @@ -283,26 +282,12 @@ export class MetadataService { return true; } - async handleSidecarSync() { - // TODO: optimize to only queue assets with recent xmp changes - return true; + handleSidecarSync({ id }: IEntityJob) { + return this.processSidecar(id, true); } - async handleSidecarDiscovery({ id }: IEntityJob) { - const [asset] = await this.assetRepository.getByIds([id]); - if (!asset || !asset.isVisible || asset.sidecarPath) { - return false; - } - - const sidecarPath = `${asset.originalPath}.xmp`; - const exists = await this.storageRepository.checkFileExists(sidecarPath, constants.R_OK); - if (!exists) { - return false; - } - - await this.assetRepository.save({ id: asset.id, sidecarPath }); - - return true; + handleSidecarDiscovery({ id }: IEntityJob) { + return this.processSidecar(id, false); } async handleSidecarWrite(job: ISidecarWriteJob) { @@ -565,4 +550,36 @@ export class MetadataService { return Duration.fromObject({ seconds: _seconds }).toFormat('hh:mm:ss.SSS'); } + + private async processSidecar(id: string, isSync: boolean) { + const [asset] = await this.assetRepository.getByIds([id]); + + if (!asset) { + return false; + } + + if (isSync && !asset.sidecarPath) { + return false; + } + + if (!isSync && (!asset.isVisible || asset.sidecarPath)) { + return false; + } + + const sidecarPath = `${asset.originalPath}.xmp`; + const exists = await this.storageRepository.checkFileExists(sidecarPath, constants.R_OK); + if (exists) { + await this.assetRepository.save({ id: asset.id, sidecarPath }); + return true; + } + + if (!isSync) { + return false; + } + + this.logger.debug(`Sidecar File '${sidecarPath}' was not found, removing sidecarPath for asset ${asset.id}`); + await this.assetRepository.save({ id: asset.id, sidecarPath: null }); + + return true; + } } diff --git a/server/src/microservices/app.service.ts b/server/src/microservices/app.service.ts index 3109b7f782..df1d9938b5 100644 --- a/server/src/microservices/app.service.ts +++ b/server/src/microservices/app.service.ts @@ -72,7 +72,7 @@ export class AppService { [JobName.PERSON_CLEANUP]: () => this.personService.handlePersonCleanup(), [JobName.QUEUE_SIDECAR]: (data) => this.metadataService.handleQueueSidecar(data), [JobName.SIDECAR_DISCOVERY]: (data) => this.metadataService.handleSidecarDiscovery(data), - [JobName.SIDECAR_SYNC]: () => this.metadataService.handleSidecarSync(), + [JobName.SIDECAR_SYNC]: (data) => this.metadataService.handleSidecarSync(data), [JobName.SIDECAR_WRITE]: (data) => this.metadataService.handleSidecarWrite(data), [JobName.LIBRARY_SCAN_ASSET]: (data) => this.libraryService.handleAssetRefresh(data), [JobName.LIBRARY_SCAN]: (data) => this.libraryService.handleQueueAssetRefresh(data), From de3ded9db02b1f9ffc3bea2e39c8c03272d2fa53 Mon Sep 17 00:00:00 2001 From: shenlong <139912620+shenlong-tanwen@users.noreply.github.com> Date: Wed, 7 Feb 2024 20:59:48 +0000 Subject: [PATCH 036/104] chore(dep): add intl to ignoreDeps and remove unused packages (#6967) Co-authored-by: shenlong-tanwen <139912620+shalong-tanwen@users.noreply.github.com> --- renovate.json | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/renovate.json b/renovate.json index 9bc4ad6a62..7cb136b1a3 100644 --- a/renovate.json +++ b/renovate.json @@ -83,10 +83,7 @@ "ignorePaths": ["mobile/openapi/pubspec.yaml"], "ignoreDeps": [ "http", - "latlong2", - "vector_map_tiles", - "flutter_map", - "flutter_map_heatmap" + "intl" ], "labels": ["dependencies", "renovate"] } From b74c84e7714dfe1433988f924111da6544c4e6e5 Mon Sep 17 00:00:00 2001 From: Mert <101130780+mertalev@users.noreply.github.com> Date: Wed, 7 Feb 2024 21:58:39 -0500 Subject: [PATCH 037/104] fix(docs): add cuda tag to ml hwaccel example (#6972) add `-cuda` --- docs/docs/features/ml-hardware-acceleration.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/docs/features/ml-hardware-acceleration.md b/docs/docs/features/ml-hardware-acceleration.md index b50185c580..8f5a889775 100644 --- a/docs/docs/features/ml-hardware-acceleration.md +++ b/docs/docs/features/ml-hardware-acceleration.md @@ -69,7 +69,7 @@ You can add this to the `immich-machine-learning` service instead of extending f ```yaml immich-machine-learning: container_name: immich_machine_learning - image: ghcr.io/immich-app/immich-machine-learning:${IMMICH_VERSION:-release} + image: ghcr.io/immich-app/immich-machine-learning:${IMMICH_VERSION:-release}-cuda # Note the lack of an `extends` section deploy: resources: From 2010c92b614cab088b70ab4dc00f0ad1513c8958 Mon Sep 17 00:00:00 2001 From: Lukas Date: Thu, 8 Feb 2024 03:59:39 +0100 Subject: [PATCH 038/104] docs: fix web development setup instructions (#6969) --- docs/docs/developer/setup.md | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/docs/docs/developer/setup.md b/docs/docs/developer/setup.md index 7a271d980c..dc61c37d42 100644 --- a/docs/docs/developer/setup.md +++ b/docs/docs/developer/setup.md @@ -58,12 +58,13 @@ Please refer to the [Flutter's official documentation](https://flutter.dev/docs/ If you only want to do web development connected to an existing, remote backend, follow these steps: -1. Enter the web directory - `cd web/` -2. Install web dependencies - `npm i` -3. Start the web development server +1. Build the Immich SDK - `cd open-api/typescript-sdk && npm i && npm run build && cd -` +2. Enter the web directory - `cd web/` +3. Install web dependencies - `npm i` +4. Start the web development server -``` -IMMICH_SERVER_URL=https://demo.immich.app/api npm run dev +```bash +IMMICH_SERVER_URL=https://demo.immich.app/ npm run dev ``` ## IDE setup From e0864768c2e55fe7f6e2aaa3d373d24d7cb430b5 Mon Sep 17 00:00:00 2001 From: shenlong <139912620+shenlong-tanwen@users.noreply.github.com> Date: Thu, 8 Feb 2024 03:07:43 +0000 Subject: [PATCH 039/104] refactor(mobile): map heatmap color and location picker (#6553) * refactor(mobile): make location picker scaffold primary * chore(mobile): update map heatmap colors * style(mobile): map bottomsheet - only use borders on top * fix(mobile): location picker show buttons above navigation bar * fix: crash on iOS due to heatmap invalid color format * disable rotate --------- Co-authored-by: shenlong-tanwen <139912620+shalong-tanwen@users.noreply.github.com> Co-authored-by: Alex Tran --- mobile/ios/Podfile.lock | 2 +- .../extensions/build_context_extensions.dart | 8 +- mobile/lib/modules/map/utils/map_utils.dart | 21 +-- .../map/views/map_location_picker_page.dart | 150 +++++++++--------- mobile/lib/modules/map/views/map_page.dart | 12 +- .../modules/map/widgets/map_asset_grid.dart | 9 +- 6 files changed, 102 insertions(+), 100 deletions(-) diff --git a/mobile/ios/Podfile.lock b/mobile/ios/Podfile.lock index a9ac5b3381..6081988b7a 100644 --- a/mobile/ios/Podfile.lock +++ b/mobile/ios/Podfile.lock @@ -180,4 +180,4 @@ SPEC CHECKSUMS: PODFILE CHECKSUM: 64c9b5291666c0ca3caabdfe9865c141ac40321d -COCOAPODS: 1.12.1 +COCOAPODS: 1.11.3 diff --git a/mobile/lib/extensions/build_context_extensions.dart b/mobile/lib/extensions/build_context_extensions.dart index 3b99718d79..6a61b00530 100644 --- a/mobile/lib/extensions/build_context_extensions.dart +++ b/mobile/lib/extensions/build_context_extensions.dart @@ -1,14 +1,14 @@ import 'package:flutter/material.dart'; extension ContextHelper on BuildContext { - // Returns the current size from MediaQuery - Size get size => MediaQuery.sizeOf(this); + // Returns the current padding from MediaQuery + EdgeInsets get padding => MediaQuery.paddingOf(this); // Returns the current width from MediaQuery - double get width => size.width; + double get width => MediaQuery.sizeOf(this).width; // Returns the current height from MediaQuery - double get height => size.height; + double get height => MediaQuery.sizeOf(this).height; // Returns true if the app is running on a mobile device (!tablets) bool get isMobile => width < 550; diff --git a/mobile/lib/modules/map/utils/map_utils.dart b/mobile/lib/modules/map/utils/map_utils.dart index 5fec97ea03..46af81ce1d 100644 --- a/mobile/lib/modules/map/utils/map_utils.dart +++ b/mobile/lib/modules/map/utils/map_utils.dart @@ -19,17 +19,17 @@ class MapUtils { ["linear"], ["heatmap-density"], 0.0, - "rgba(246,239,247,0.0)", - 0.2, - "rgb(208,209,230)", - 0.4, - "rgb(166,189,219)", - 0.6, - "rgb(103,169,207)", - 0.8, - "rgb(28,144,153)", + "rgba(103,58,183,0.0)", + 0.3, + "rgb(103,58,183)", + 0.5, + "rgb(33,149,243)", + 0.7, + "rgb(76,175,79)", + 0.95, + "rgb(255,235,59)", 1.0, - "rgb(1,108,89)", + "rgb(255,86,34)", ], heatmapIntensity: [ Expressions.interpolate, ["linear"], // @@ -44,6 +44,7 @@ class MapUtils { 4, 8, 9, 16, ], + heatmapOpacity: 0.7, ); static Map _addFeature(MapMarker marker) => { diff --git a/mobile/lib/modules/map/views/map_location_picker_page.dart b/mobile/lib/modules/map/views/map_location_picker_page.dart index a232638f74..b41c1184c1 100644 --- a/mobile/lib/modules/map/views/map_location_picker_page.dart +++ b/mobile/lib/modules/map/views/map_location_picker_page.dart @@ -11,7 +11,6 @@ import 'package:immich_mobile/extensions/maplibrecontroller_extensions.dart'; import 'package:immich_mobile/modules/map/widgets/map_theme_override.dart'; import 'package:maplibre_gl/maplibre_gl.dart'; import 'package:immich_mobile/modules/map/utils/map_utils.dart'; -import 'package:geolocator/geolocator.dart'; @RoutePage() class MapLocationPickerPage extends HookConsumerWidget { @@ -46,15 +45,13 @@ class MapLocationPickerPage extends HookConsumerWidget { } Future getCurrentLocation() async { - var (currentLocation, locationPermission) = + var (currentLocation, _) = await MapUtils.checkPermAndGetLocation(context); - if (locationPermission == LocationPermission.denied || - locationPermission == LocationPermission.deniedForever) { - return; - } + if (currentLocation == null) { return; } + var currentLatLng = LatLng(currentLocation.latitude, currentLocation.longitude); selectedLatLng.value = currentLatLng; @@ -67,40 +64,35 @@ class MapLocationPickerPage extends HookConsumerWidget { backgroundColor: ctx.themeData.cardColor, appBar: _AppBar(onClose: onClose), extendBodyBehindAppBar: true, - body: Column( - children: [ - style.widgetWhen( - onData: (style) => Expanded( - child: Container( - clipBehavior: Clip.antiAliasWithSaveLayer, - decoration: const BoxDecoration( - borderRadius: BorderRadius.only( - bottomLeft: Radius.circular(40), - bottomRight: Radius.circular(40), - ), - ), - child: MaplibreMap( - initialCameraPosition: - CameraPosition(target: initialLatLng, zoom: 12), - styleString: style, - onMapCreated: (mapController) => - controller.value = mapController, - onStyleLoadedCallback: onStyleLoaded, - onMapClick: onMapClick, - dragEnabled: false, - tiltGesturesEnabled: false, - myLocationEnabled: false, - attributionButtonMargins: const Point(20, 15), - ), - ), + primary: true, + body: style.widgetWhen( + onData: (style) => Container( + clipBehavior: Clip.antiAliasWithSaveLayer, + decoration: const BoxDecoration( + borderRadius: BorderRadius.only( + bottomLeft: Radius.circular(40), + bottomRight: Radius.circular(40), ), ), - _BottomBar( - selectedLatLng: selectedLatLng, - onUseLocation: () => onClose(selectedLatLng.value), - onGetCurrentLocation: getCurrentLocation, + child: MaplibreMap( + initialCameraPosition: + CameraPosition(target: initialLatLng, zoom: 12), + styleString: style, + onMapCreated: (mapController) => + controller.value = mapController, + onStyleLoadedCallback: onStyleLoaded, + onMapClick: onMapClick, + dragEnabled: false, + tiltGesturesEnabled: false, + myLocationEnabled: false, + attributionButtonMargins: const Point(20, 15), ), - ], + ), + ), + bottomNavigationBar: _BottomBar( + selectedLatLng: selectedLatLng, + onUseLocation: () => onClose(selectedLatLng.value), + onGetCurrentLocation: getCurrentLocation, ), ), ), @@ -116,17 +108,15 @@ class _AppBar extends StatelessWidget implements PreferredSizeWidget { @override Widget build(BuildContext context) { return Padding( - padding: EdgeInsets.only(top: MediaQuery.paddingOf(context).top + 25), - child: Expanded( - child: Align( - alignment: Alignment.centerLeft, - child: ElevatedButton( - onPressed: onClose, - style: ElevatedButton.styleFrom( - shape: const CircleBorder(), - ), - child: const Icon(Icons.arrow_back_ios_new_rounded), + padding: const EdgeInsets.only(top: 25), + child: Align( + alignment: Alignment.centerLeft, + child: ElevatedButton( + onPressed: onClose, + style: ElevatedButton.styleFrom( + shape: const CircleBorder(), ), + child: const Icon(Icons.arrow_back_ios_new_rounded), ), ), ); @@ -150,38 +140,42 @@ class _BottomBar extends StatelessWidget { @override Widget build(BuildContext context) { return SizedBox( - height: 150, - child: Column( - mainAxisAlignment: MainAxisAlignment.spaceEvenly, - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Row( - mainAxisAlignment: MainAxisAlignment.center, - children: [ - const Icon(Icons.public, size: 18), - const SizedBox(width: 15), - ValueListenableBuilder( - valueListenable: selectedLatLng, - builder: (_, value, __) => Text( - "${value.latitude.toStringAsFixed(4)}, ${value.longitude.toStringAsFixed(4)}", + height: 150 + context.padding.bottom, + child: Padding( + padding: EdgeInsets.only(bottom: context.padding.bottom), + child: Column( + mainAxisAlignment: MainAxisAlignment.spaceEvenly, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Row( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + const Icon(Icons.public, size: 18), + const SizedBox(width: 15), + ValueListenableBuilder( + valueListenable: selectedLatLng, + builder: (_, value, __) => Text( + "${value.latitude.toStringAsFixed(4)}, ${value.longitude.toStringAsFixed(4)}", + ), ), - ), - ], - ), - Row( - mainAxisAlignment: MainAxisAlignment.spaceEvenly, - children: [ - ElevatedButton( - onPressed: onUseLocation, - child: const Text("map_location_picker_page_use_location").tr(), - ), - ElevatedButton( - onPressed: onGetCurrentLocation, - child: const Icon(Icons.my_location), - ), - ], - ), - ], + ], + ), + Row( + mainAxisAlignment: MainAxisAlignment.spaceEvenly, + children: [ + ElevatedButton( + onPressed: onUseLocation, + child: + const Text("map_location_picker_page_use_location").tr(), + ), + ElevatedButton( + onPressed: onGetCurrentLocation, + child: const Icon(Icons.my_location), + ), + ], + ), + ], + ), ), ); } diff --git a/mobile/lib/modules/map/views/map_page.dart b/mobile/lib/modules/map/views/map_page.dart index 671e501bcc..f1b9addb13 100644 --- a/mobile/lib/modules/map/views/map_page.dart +++ b/mobile/lib/modules/map/views/map_page.dart @@ -220,10 +220,9 @@ class MapPage extends HookConsumerWidget { } void onZoomToLocation() async { - final location = await MapUtils.checkPermAndGetLocation(context); - if (location.$2 != null) { - if (location.$2 == LocationPermission.unableToDetermine && - context.mounted) { + final (location, error) = await MapUtils.checkPermAndGetLocation(context); + if (error != null) { + if (error == LocationPermission.unableToDetermine && context.mounted) { ImmichToast.show( context: context, gravity: ToastGravity.BOTTOM, @@ -234,10 +233,10 @@ class MapPage extends HookConsumerWidget { return; } - if (mapController.value != null && location.$1 != null) { + if (mapController.value != null && location != null) { mapController.value!.animateCamera( CameraUpdate.newLatLngZoom( - LatLng(location.$1!.latitude, location.$1!.longitude), + LatLng(location.latitude, location.longitude), mapZoomToAssetLevel, ), duration: const Duration(milliseconds: 800), @@ -389,6 +388,7 @@ class _MapWithMarker extends StatelessWidget { dragEnabled: false, myLocationEnabled: false, attributionButtonPosition: AttributionButtonPosition.TopRight, + rotateGesturesEnabled: false, ), ), ValueListenableBuilder( diff --git a/mobile/lib/modules/map/widgets/map_asset_grid.dart b/mobile/lib/modules/map/widgets/map_asset_grid.dart index 411039f981..d1f187e258 100644 --- a/mobile/lib/modules/map/widgets/map_asset_grid.dart +++ b/mobile/lib/modules/map/widgets/map_asset_grid.dart @@ -231,7 +231,14 @@ class _MapSheetDragRegion extends StatelessWidget { physics: const ClampingScrollPhysics(), child: Card( margin: EdgeInsets.zero, - shape: context.isMobile ? null : const BeveledRectangleBorder(), + shape: context.isMobile + ? const RoundedRectangleBorder( + borderRadius: BorderRadius.only( + topRight: Radius.circular(20), + topLeft: Radius.circular(20), + ), + ) + : const BeveledRectangleBorder(), elevation: 0.0, child: Stack( children: [ From 0d876a470f2b51d0f507bb5f9047c0d54966838e Mon Sep 17 00:00:00 2001 From: martyfuhry Date: Wed, 7 Feb 2024 22:54:54 -0500 Subject: [PATCH 040/104] feat(mobile): Adds WiFi only backup option to iOS (#6724) Adds WiFi only backup option to iOS Co-authored-by: Marty Fuhry Co-authored-by: Alex Tran --- .../BackgroundServicePlugin.swift | 19 +++++++++++++++++-- .../backup/views/backup_options_page.dart | 2 +- 2 files changed, 18 insertions(+), 3 deletions(-) diff --git a/mobile/ios/Runner/BackgroundSync/BackgroundServicePlugin.swift b/mobile/ios/Runner/BackgroundSync/BackgroundServicePlugin.swift index 8e5db08b1e..c84b037daf 100644 --- a/mobile/ios/Runner/BackgroundSync/BackgroundServicePlugin.swift +++ b/mobile/ios/Runner/BackgroundSync/BackgroundServicePlugin.swift @@ -9,6 +9,7 @@ import Flutter import BackgroundTasks import path_provider_foundation import CryptoKit +import Network class BackgroundServicePlugin: NSObject, FlutterPlugin { @@ -335,8 +336,8 @@ class BackgroundServicePlugin: NSObject, FlutterPlugin { defaults.set(Date().timeIntervalSince1970, forKey: "last_background_fetch_run_time") // If we have required charging, we should check the charging status - let requireCharging = defaults.value(forKey: "require_charging") as? Bool - if (requireCharging ?? false) { + let requireCharging = defaults.value(forKey: "require_charging") as? Bool ?? false + if (requireCharging) { UIDevice.current.isBatteryMonitoringEnabled = true if (UIDevice.current.batteryState == .unplugged) { // The device is unplugged and we have required charging @@ -347,6 +348,20 @@ class BackgroundServicePlugin: NSObject, FlutterPlugin { } } + // If we have required Wi-Fi, we can check the isExpensive property + let requireWifi = defaults.value(forKey: "require_wifi") as? Bool ?? false + if (requireWifi) { + let wifiMonitor = NWPathMonitor(requiredInterfaceType: .wifi) + let isExpensive = wifiMonitor.currentPath.isExpensive + if (isExpensive) { + // The network is expensive and we have required Wi-Fi + // Therfore, we will simply complete the task without + // running it + task.setTaskCompleted(success: true) + return + } + } + // Schedule the next sync task so we can run this again later scheduleBackgroundFetch() diff --git a/mobile/lib/modules/backup/views/backup_options_page.dart b/mobile/lib/modules/backup/views/backup_options_page.dart index c3beb2f8c5..8144f1b8ed 100644 --- a/mobile/lib/modules/backup/views/backup_options_page.dart +++ b/mobile/lib/modules/backup/views/backup_options_page.dart @@ -264,7 +264,7 @@ class BackupOptionsPage extends HookConsumerWidget { "backup_controller_page_background_description", ).tr(), ), - if (isBackgroundEnabled && Platform.isAndroid) + if (isBackgroundEnabled) SwitchListTile.adaptive( title: const Text("backup_controller_page_background_wifi") .tr(), From 69091e530950287070f079ceb687b47a326f90dc Mon Sep 17 00:00:00 2001 From: martyfuhry Date: Wed, 7 Feb 2024 23:07:50 -0500 Subject: [PATCH 041/104] feat(mobile): Videos play in memories now (#6940) * Videos play in memories now Remove auto video advance * to next asset after video is done playing --------- Co-authored-by: Alex Tran --- .../asset_viewer/views/video_viewer_page.dart | 80 ++++++++++++------- .../lib/modules/memories/ui/memory_card.dart | 57 ++++++++----- .../modules/memories/views/memory_page.dart | 22 +++-- 3 files changed, 104 insertions(+), 55 deletions(-) diff --git a/mobile/lib/modules/asset_viewer/views/video_viewer_page.dart b/mobile/lib/modules/asset_viewer/views/video_viewer_page.dart index 8257f28578..72aa397f67 100644 --- a/mobile/lib/modules/asset_viewer/views/video_viewer_page.dart +++ b/mobile/lib/modules/asset_viewer/views/video_viewer_page.dart @@ -21,40 +21,45 @@ class VideoViewerPage extends HookConsumerWidget { final Asset asset; final bool isMotionVideo; final Widget? placeholder; - final VoidCallback onVideoEnded; + final VoidCallback? onVideoEnded; final VoidCallback? onPlaying; final VoidCallback? onPaused; + final Duration hideControlsTimer; + final bool showControls; + final bool showDownloadingIndicator; const VideoViewerPage({ super.key, required this.asset, - required this.isMotionVideo, - required this.onVideoEnded, + this.isMotionVideo = false, + this.onVideoEnded, this.onPlaying, this.onPaused, this.placeholder, + this.showControls = true, + this.hideControlsTimer = const Duration(seconds: 5), + this.showDownloadingIndicator = true, }); @override Widget build(BuildContext context, WidgetRef ref) { if (asset.isLocal && asset.livePhotoVideoId == null) { final AsyncValue videoFile = ref.watch(_fileFamily(asset.local!)); - return videoFile.when( - data: (data) => VideoPlayer( - file: data, - isMotionVideo: false, - onVideoEnded: () {}, - ), - error: (error, stackTrace) => Icon( - Icons.image_not_supported_outlined, - color: context.primaryColor, - ), - loading: () => const Center( - child: SizedBox( - width: 75, - height: 75, - child: CircularProgressIndicator.adaptive(), + return AnimatedSwitcher( + duration: const Duration(milliseconds: 200), + child: videoFile.when( + data: (data) => VideoPlayer( + file: data, + isMotionVideo: false, + onVideoEnded: () {}, ), + error: (error, stackTrace) => Icon( + Icons.image_not_supported_outlined, + color: context.primaryColor, + ), + loading: () => showDownloadingIndicator + ? const Center(child: ImmichLoadingIndicator()) + : Container(), ), ); } @@ -74,15 +79,24 @@ class VideoViewerPage extends HookConsumerWidget { onPaused: onPaused, onPlaying: onPlaying, placeholder: placeholder, + hideControlsTimer: hideControlsTimer, + showControls: showControls, + showDownloadingIndicator: showDownloadingIndicator, ), - if (downloadAssetStatus == DownloadAssetStatus.loading) - SizedBox( + AnimatedOpacity( + duration: const Duration(milliseconds: 400), + opacity: (downloadAssetStatus == DownloadAssetStatus.loading && + showDownloadingIndicator) + ? 1.0 + : 0.0, + child: SizedBox( height: context.height, width: context.width, child: const Center( child: ImmichLoadingIndicator(), ), ), + ), ], ); } @@ -102,7 +116,9 @@ class VideoPlayer extends StatefulWidget { final String? accessToken; final File? file; final bool isMotionVideo; - final VoidCallback onVideoEnded; + final VoidCallback? onVideoEnded; + final Duration hideControlsTimer; + final bool showControls; final Function()? onPlaying; final Function()? onPaused; @@ -111,16 +127,23 @@ class VideoPlayer extends StatefulWidget { /// usually, a thumbnail of the video final Widget? placeholder; + final bool showDownloadingIndicator; + const VideoPlayer({ super.key, this.url, this.accessToken, this.file, - required this.onVideoEnded, + this.onVideoEnded, required this.isMotionVideo, this.onPlaying, this.onPaused, this.placeholder, + this.hideControlsTimer = const Duration( + seconds: 5, + ), + this.showControls = true, + this.showDownloadingIndicator = true, }); @override @@ -149,7 +172,7 @@ class _VideoPlayerState extends State { if (videoPlayerController.value.position == videoPlayerController.value.duration) { WakelockPlus.disable(); - widget.onVideoEnded(); + widget.onVideoEnded?.call(); } } }); @@ -184,9 +207,9 @@ class _VideoPlayerState extends State { autoInitialize: true, allowFullScreen: false, allowedScreenSleep: false, - showControls: !widget.isMotionVideo, + showControls: widget.showControls && !widget.isMotionVideo, customControls: const VideoPlayerControls(), - hideControlsTimer: const Duration(seconds: 5), + hideControlsTimer: widget.hideControlsTimer, ); } @@ -216,9 +239,10 @@ class _VideoPlayerState extends State { child: Stack( children: [ if (widget.placeholder != null) widget.placeholder!, - const Center( - child: ImmichLoadingIndicator(), - ), + if (widget.showDownloadingIndicator) + const Center( + child: ImmichLoadingIndicator(), + ), ], ), ), diff --git a/mobile/lib/modules/memories/ui/memory_card.dart b/mobile/lib/modules/memories/ui/memory_card.dart index f9231338c5..364a88b47c 100644 --- a/mobile/lib/modules/memories/ui/memory_card.dart +++ b/mobile/lib/modules/memories/ui/memory_card.dart @@ -3,6 +3,7 @@ import 'dart:ui'; import 'package:cached_network_image/cached_network_image.dart'; import 'package:flutter/material.dart'; import 'package:immich_mobile/extensions/build_context_extensions.dart'; +import 'package:immich_mobile/modules/asset_viewer/views/video_viewer_page.dart'; import 'package:immich_mobile/shared/models/asset.dart'; import 'package:immich_mobile/shared/models/store.dart'; import 'package:immich_mobile/shared/ui/immich_image.dart'; @@ -11,15 +12,15 @@ import 'package:openapi/api.dart'; class MemoryCard extends StatelessWidget { final Asset asset; - final void Function() onTap; final String title; final bool showTitle; + final Function()? onVideoEnded; const MemoryCard({ required this.asset, - required this.onTap, required this.title, required this.showTitle, + this.onVideoEnded, super.key, }); @@ -59,24 +60,23 @@ class MemoryCard extends StatelessWidget { child: Container(color: Colors.black.withOpacity(0.2)), ), ), - GestureDetector( - onTap: onTap, - child: LayoutBuilder( - builder: (context, constraints) { - // Determine the fit using the aspect ratio - BoxFit fit = BoxFit.fitWidth; - if (asset.width != null && asset.height != null) { - final aspectRatio = asset.width! / asset.height!; - final phoneAspectRatio = - constraints.maxWidth / constraints.maxHeight; - // Look for a 25% difference in either direction - if (phoneAspectRatio * .75 < aspectRatio && - phoneAspectRatio * 1.25 > aspectRatio) { - // Cover to look nice if we have nearly the same aspect ratio - fit = BoxFit.cover; - } + LayoutBuilder( + builder: (context, constraints) { + // Determine the fit using the aspect ratio + BoxFit fit = BoxFit.fitWidth; + if (asset.width != null && asset.height != null) { + final aspectRatio = asset.height! / asset.width!; + final phoneAspectRatio = + constraints.maxWidth / constraints.maxHeight; + // Look for a 25% difference in either direction + if (phoneAspectRatio * .75 < aspectRatio && + phoneAspectRatio * 1.25 > aspectRatio) { + // Cover to look nice if we have nearly the same aspect ratio + fit = BoxFit.cover; } + } + if (asset.isImage) { return Hero( tag: 'memory-${asset.id}', child: ImmichImage( @@ -88,8 +88,25 @@ class MemoryCard extends StatelessWidget { preferredLocalAssetSize: 2048, ), ); - }, - ), + } else { + return Hero( + tag: 'memory-${asset.id}', + child: VideoViewerPage( + asset: asset, + showDownloadingIndicator: false, + placeholder: ImmichImage( + asset, + fit: fit, + type: ThumbnailFormat.JPEG, + preferredLocalAssetSize: 2048, + ), + hideControlsTimer: const Duration(seconds: 2), + onVideoEnded: onVideoEnded, + showControls: false, + ), + ); + } + }, ), if (showTitle) Positioned( diff --git a/mobile/lib/modules/memories/views/memory_page.dart b/mobile/lib/modules/memories/views/memory_page.dart index 26104054c3..63f4e7df04 100644 --- a/mobile/lib/modules/memories/views/memory_page.dart +++ b/mobile/lib/modules/memories/views/memory_page.dart @@ -245,13 +245,21 @@ class MemoryPage extends HookConsumerWidget { itemCount: memories[mIndex].assets.length, itemBuilder: (context, index) { final asset = memories[mIndex].assets[index]; - return Container( - color: Colors.black, - child: MemoryCard( - asset: asset, - onTap: () => toNextAsset(index), - title: memories[mIndex].title, - showTitle: index == 0, + return GestureDetector( + behavior: HitTestBehavior.translucent, + onTap: () { + toNextAsset(index); + }, + child: Container( + color: Colors.black, + child: MemoryCard( + asset: asset, + title: memories[mIndex].title, + showTitle: index == 0, + onVideoEnded: () { + toNextAsset(index); + }, + ), ), ); }, From abb6922c2b79edae50dcf3e74762c16ca50350d6 Mon Sep 17 00:00:00 2001 From: Lukas Date: Thu, 8 Feb 2024 05:15:51 +0100 Subject: [PATCH 042/104] fix: set default thumbnail aspect ratio to square (#6970) --- web/src/lib/components/assets/thumbnail/image-thumbnail.svelte | 1 + 1 file changed, 1 insertion(+) diff --git a/web/src/lib/components/assets/thumbnail/image-thumbnail.svelte b/web/src/lib/components/assets/thumbnail/image-thumbnail.svelte index c7aa0b6d83..9c82ad77b7 100644 --- a/web/src/lib/components/assets/thumbnail/image-thumbnail.svelte +++ b/web/src/lib/components/assets/thumbnail/image-thumbnail.svelte @@ -47,6 +47,7 @@ class:rounded-xl={curve} class:shadow-lg={shadow} class:rounded-full={circle} + class:aspect-square={circle || !heightStyle} class:opacity-0={!thumbhash && !complete} draggable="false" /> From b273ea2ba42cdedc9b3c6b3a2b48d881307ca626 Mon Sep 17 00:00:00 2001 From: Ben McCann <322311+benmccann@users.noreply.github.com> Date: Wed, 7 Feb 2024 23:27:54 -0800 Subject: [PATCH 043/104] chore: setup `rollup-plugin-visualizer` and remove `lodash` (#6974) * chore: setup rollup-plugin-visualizer * chore: remove lodash * format * remove lodash-es from build --- web/package-lock.json | 236 ++++++++++++++++++ web/package.json | 1 + .../lib/components/elements/dropdown.svelte | 4 +- web/src/lib/utils/timeline-util.ts | 5 +- .../routes/admin/system-settings/+page.svelte | 1 - web/vite.config.js | 37 +-- 6 files changed, 261 insertions(+), 23 deletions(-) diff --git a/web/package-lock.json b/web/package-lock.json index 9f20610d9b..3347b2cacb 100644 --- a/web/package-lock.json +++ b/web/package-lock.json @@ -50,6 +50,7 @@ "postcss": "^8.4.21", "prettier": "^3.1.0", "prettier-plugin-svelte": "^3.1.2", + "rollup-plugin-visualizer": "^5.12.0", "svelte": "^4.0.5", "svelte-check": "^3.4.3", "svelte-preprocess": "^5.0.3", @@ -2944,6 +2945,20 @@ "node": ">=4" } }, + "node_modules/cliui": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz", + "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==", + "dev": true, + "dependencies": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.1", + "wrap-ansi": "^7.0.0" + }, + "engines": { + "node": ">=12" + } + }, "node_modules/clone-deep": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/clone-deep/-/clone-deep-4.0.1.tgz", @@ -3233,6 +3248,15 @@ "node": ">= 0.4" } }, + "node_modules/define-lazy-prop": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/define-lazy-prop/-/define-lazy-prop-2.0.0.tgz", + "integrity": "sha512-Ds09qNh8yw3khSjiJjiUInaGX9xlqZDY7JVryGxdxV7NPeuqQfplOpQ66yJFZut3jLa5zOwkXw1g9EI2uKh4Og==", + "dev": true, + "engines": { + "node": ">=8" + } + }, "node_modules/define-properties": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.2.1.tgz", @@ -3348,6 +3372,12 @@ "integrity": "sha512-X4ze/9Sc3QWs6h92yerwqv7aB/uU8vCjZcrMjA8N9R1pjMFRe44dLsck5FzLilOYvcXuDn93B+bpGYyufc70gQ==", "dev": true }, + "node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true + }, "node_modules/engine.io-client": { "version": "6.5.2", "resolved": "https://registry.npmjs.org/engine.io-client/-/engine.io-client-6.5.2.tgz", @@ -4200,6 +4230,15 @@ "resolved": "https://registry.npmjs.org/geojson-vt/-/geojson-vt-3.2.1.tgz", "integrity": "sha512-EvGQQi/zPrDA6zr6BnJD/YhwAkBP8nnJ9emh3EnHQKVMfg/MRVtPbMYdgVy/IaEmn4UfagD2a6fafPDL5hbtwg==" }, + "node_modules/get-caller-file": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", + "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", + "dev": true, + "engines": { + "node": "6.* || 8.* || >= 10.*" + } + }, "node_modules/get-func-name": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/get-func-name/-/get-func-name-2.0.2.tgz", @@ -4823,6 +4862,21 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/is-docker": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/is-docker/-/is-docker-2.2.1.tgz", + "integrity": "sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ==", + "dev": true, + "bin": { + "is-docker": "cli.js" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/is-extendable": { "version": "0.1.1", "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", @@ -4840,6 +4894,15 @@ "node": ">=0.10.0" } }, + "node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true, + "engines": { + "node": ">=8" + } + }, "node_modules/is-glob": { "version": "4.0.3", "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", @@ -5037,6 +5100,18 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/is-wsl": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-2.2.0.tgz", + "integrity": "sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww==", + "dev": true, + "dependencies": { + "is-docker": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/isarray": { "version": "2.0.5", "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.5.tgz", @@ -5897,6 +5972,23 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/open": { + "version": "8.4.2", + "resolved": "https://registry.npmjs.org/open/-/open-8.4.2.tgz", + "integrity": "sha512-7x81NCL719oNbsq/3mh+hVrAWmFuEYUqrq/Iw3kUzH8ReypT9QQ0BLoJS7/G9k6N81XjW4qHWtjWwe/9eLy1EQ==", + "dev": true, + "dependencies": { + "define-lazy-prop": "^2.0.0", + "is-docker": "^2.1.1", + "is-wsl": "^2.2.0" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/optionator": { "version": "0.9.3", "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.3.tgz", @@ -6633,6 +6725,15 @@ "jsesc": "bin/jsesc" } }, + "node_modules/require-directory": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", + "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/requires-port": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz", @@ -6723,6 +6824,41 @@ "fsevents": "~2.3.2" } }, + "node_modules/rollup-plugin-visualizer": { + "version": "5.12.0", + "resolved": "https://registry.npmjs.org/rollup-plugin-visualizer/-/rollup-plugin-visualizer-5.12.0.tgz", + "integrity": "sha512-8/NU9jXcHRs7Nnj07PF2o4gjxmm9lXIrZ8r175bT9dK8qoLlvKTwRMArRCMgpMGlq8CTLugRvEmyMeMXIU2pNQ==", + "dev": true, + "dependencies": { + "open": "^8.4.0", + "picomatch": "^2.3.1", + "source-map": "^0.7.4", + "yargs": "^17.5.1" + }, + "bin": { + "rollup-plugin-visualizer": "dist/bin/cli.js" + }, + "engines": { + "node": ">=14" + }, + "peerDependencies": { + "rollup": "2.x || 3.x || 4.x" + }, + "peerDependenciesMeta": { + "rollup": { + "optional": true + } + } + }, + "node_modules/rollup-plugin-visualizer/node_modules/source-map": { + "version": "0.7.4", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.4.tgz", + "integrity": "sha512-l3BikUxvPOcn5E74dZiq5BGsTb5yEwhaTSzccU6t4sDOH8NWJCstKO5QT2CvtFoK6F0saL7p9xHAqHOlCPJygA==", + "dev": true, + "engines": { + "node": ">= 8" + } + }, "node_modules/rrweb-cssom": { "version": "0.6.0", "resolved": "https://registry.npmjs.org/rrweb-cssom/-/rrweb-cssom-0.6.0.tgz", @@ -7139,6 +7275,20 @@ "node": ">= 0.4" } }, + "node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/strip-ansi": { "version": "6.0.1", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", @@ -8230,6 +8380,56 @@ "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz", "integrity": "sha512-gvVzJFlPycKc5dZN4yPkP8w7Dc37BtP1yczEneOb4uq34pXZcvrtRTmWV8W+Ume+XCxKgbjM+nevkyFPMybd4Q==" }, + "node_modules/wrap-ansi": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/wrap-ansi/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/wrap-ansi/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/wrap-ansi/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, "node_modules/wrappy": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", @@ -8286,6 +8486,15 @@ "node": ">=0.4.0" } }, + "node_modules/y18n": { + "version": "5.0.8", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", + "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", + "dev": true, + "engines": { + "node": ">=10" + } + }, "node_modules/yallist": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", @@ -8303,6 +8512,33 @@ "node": ">= 6" } }, + "node_modules/yargs": { + "version": "17.7.2", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz", + "integrity": "sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==", + "dev": true, + "dependencies": { + "cliui": "^8.0.1", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", + "require-directory": "^2.1.1", + "string-width": "^4.2.3", + "y18n": "^5.0.5", + "yargs-parser": "^21.1.1" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/yargs-parser": { + "version": "21.1.1", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz", + "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==", + "dev": true, + "engines": { + "node": ">=12" + } + }, "node_modules/yocto-queue": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", diff --git a/web/package.json b/web/package.json index a1ead3d9a4..90be3a1235 100644 --- a/web/package.json +++ b/web/package.json @@ -45,6 +45,7 @@ "postcss": "^8.4.21", "prettier": "^3.1.0", "prettier-plugin-svelte": "^3.1.2", + "rollup-plugin-visualizer": "^5.12.0", "svelte": "^4.0.5", "svelte-check": "^3.4.3", "svelte-preprocess": "^5.0.3", diff --git a/web/src/lib/components/elements/dropdown.svelte b/web/src/lib/components/elements/dropdown.svelte index 57757dafdb..58eeef0e4d 100644 --- a/web/src/lib/components/elements/dropdown.svelte +++ b/web/src/lib/components/elements/dropdown.svelte @@ -9,7 +9,7 @@ import { mdiCheck } from '@mdi/js'; - import _ from 'lodash'; + import { isEqual } from 'lodash-es'; import LinkButton from './buttons/link-button.svelte'; import { clickOutside } from '$lib/utils/click-outside'; import { fly } from 'svelte/transition'; @@ -92,7 +92,7 @@ class="grid grid-cols-[20px,1fr] place-items-center p-2 transition-all hover:bg-gray-300 dark:hover:bg-gray-800" on:click={() => handleSelectOption(option)} > - {#if _.isEqual(selectedOption, option)} + {#if isEqual(selectedOption, option)}
diff --git a/web/src/lib/utils/timeline-util.ts b/web/src/lib/utils/timeline-util.ts index c9dd89db53..10422e59e2 100644 --- a/web/src/lib/utils/timeline-util.ts +++ b/web/src/lib/utils/timeline-util.ts @@ -1,5 +1,5 @@ import type { AssetResponseDto } from '@api'; -import lodash from 'lodash-es'; +import { chain } from 'lodash-es'; import { DateTime, Interval } from 'luxon'; export const fromLocalDateTime = (localDateTime: string) => DateTime.fromISO(localDateTime, { zone: 'UTC' }); @@ -45,8 +45,7 @@ export function splitBucketIntoDateGroups( assets: AssetResponseDto[], locale: string | undefined, ): AssetResponseDto[][] { - return lodash - .chain(assets) + return chain(assets) .groupBy((asset) => fromLocalDateTime(asset.localDateTime).toLocaleString(groupDateFormat, { locale })) .sortBy((group) => assets.indexOf(group[0])) .value(); diff --git a/web/src/routes/admin/system-settings/+page.svelte b/web/src/routes/admin/system-settings/+page.svelte index e91809c063..a52f797ccb 100644 --- a/web/src/routes/admin/system-settings/+page.svelte +++ b/web/src/routes/admin/system-settings/+page.svelte @@ -24,7 +24,6 @@ import LibrarySettings from '$lib/components/admin-page/settings/library-settings/library-settings.svelte'; import LoggingSettings from '$lib/components/admin-page/settings/logging-settings/logging-settings.svelte'; import { mdiAlert, mdiContentCopy, mdiDownload } from '@mdi/js'; - import _ from 'lodash'; import AdminSettings from '$lib/components/admin-page/settings/admin-settings.svelte'; export let data: PageData; diff --git a/web/vite.config.js b/web/vite.config.js index ea49b8cc47..f26b1bf614 100644 --- a/web/vite.config.js +++ b/web/vite.config.js @@ -1,4 +1,6 @@ import { sveltekit } from '@sveltejs/kit/vite'; +import { visualizer } from 'rollup-plugin-visualizer'; +import { defineConfig } from 'vite'; import path from 'node:path'; const upstream = { @@ -9,8 +11,7 @@ const upstream = { ws: true, }; -/** @type {import('vite').UserConfig} */ -const config = { +export default defineConfig({ resolve: { alias: { 'xmlhttprequest-ssl': './node_modules/engine.io-client/lib/xmlhttprequest.js', @@ -27,22 +28,24 @@ const config = { '/custom.css': upstream, }, }, - plugins: [sveltekit()], + plugins: [ + sveltekit(), + visualizer({ + emitFile: true, + filename: 'stats.html', + }), + ], optimizeDeps: { entries: ['src/**/*.{svelte,ts,html}'], }, -}; - -/** @type {import('vitest').UserConfig} */ -const test = { - include: ['src/**/*.{test,spec}.{js,ts}'], - globals: true, - environment: 'jsdom', - setupFiles: ['./src/test-data/setup.ts'], - sequence: { - hooks: 'list', + test: { + include: ['src/**/*.{test,spec}.{js,ts}'], + globals: true, + environment: 'jsdom', + setupFiles: ['./src/test-data/setup.ts'], + sequence: { + hooks: 'list', + }, + alias: [{ find: /^svelte$/, replacement: 'svelte/internal' }], }, - alias: [{ find: /^svelte$/, replacement: 'svelte/internal' }], -}; - -export default { ...config, test }; +}); From 36477d59c4a1d99dc53b4e378fb08465f0f73b9c Mon Sep 17 00:00:00 2001 From: Jonathan Jogenfors Date: Thu, 8 Feb 2024 17:26:24 +0100 Subject: [PATCH 044/104] chore(cli): publish docker image on ghcr (#6964) * build(cli): Docker release workflow * build(cli): Run jobs for main/PR pushes * chore(ci): Rename cli build workflow * chore(ci): Fix CLI build event paths * chore(ci): CLI build cleanup * build(cli): Fix build-push-action dockerfile ref * chore: Remove redundant comment * build(cli): Fix registry login step * build(cli): Manually define latest tag * build(cli): Only push on workflow_dispatch * build(cli): Run docker release after NPM publish --------- Co-authored-by: bo0tzz --- .github/workflows/cli-release.yml | 23 -------- .github/workflows/cli.yml | 90 +++++++++++++++++++++++++++++++ 2 files changed, 90 insertions(+), 23 deletions(-) delete mode 100644 .github/workflows/cli-release.yml create mode 100644 .github/workflows/cli.yml diff --git a/.github/workflows/cli-release.yml b/.github/workflows/cli-release.yml deleted file mode 100644 index c66dcfb3cf..0000000000 --- a/.github/workflows/cli-release.yml +++ /dev/null @@ -1,23 +0,0 @@ -name: CLI Release -on: - workflow_dispatch: - -jobs: - publish: - name: Publish - runs-on: ubuntu-latest - defaults: - run: - working-directory: ./cli - - steps: - - uses: actions/checkout@v4 - # Setup .npmrc file to publish to npm - - uses: actions/setup-node@v4 - with: - node-version: "20.x" - registry-url: "https://registry.npmjs.org" - - run: npm ci - - run: npm publish - env: - NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }} diff --git a/.github/workflows/cli.yml b/.github/workflows/cli.yml new file mode 100644 index 0000000000..57df2bb8a2 --- /dev/null +++ b/.github/workflows/cli.yml @@ -0,0 +1,90 @@ +name: CLI Build +on: + workflow_dispatch: + push: + branches: [main] + paths: + - 'cli/**' + - '.github/workflows/cli.yml' + pull_request: + branches: [main] + paths: + - 'cli/**' + - '.github/workflows/cli.yml' + +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + +permissions: + packages: write + +jobs: + publish: + name: Publish + runs-on: ubuntu-latest + defaults: + run: + working-directory: ./cli + + steps: + - uses: actions/checkout@v4 + # Setup .npmrc file to publish to npm + - uses: actions/setup-node@v4 + with: + node-version: "20.x" + registry-url: "https://registry.npmjs.org" + - run: npm ci + - run: npm publish + if: ${{ github.event_name == 'workflow_dispatch' }} + env: + NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }} + + docker: + name: Docker + runs-on: ubuntu-latest + needs: publish + + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Set up QEMU + uses: docker/setup-qemu-action@v3.0.0 + + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v3.0.0 + + - name: Login to GitHub Container Registry + uses: docker/login-action@v3 + if: ${{ !github.event.pull_request.head.repo.fork }} + with: + registry: ghcr.io + username: ${{ github.repository_owner }} + password: ${{ secrets.GITHUB_TOKEN }} + + - name: Get package version + id: package-version + run: | + version=$(jq -r '.version' cli/package.json) + echo "version=$version" >> "$GITHUB_OUTPUT" + + - name: Generate docker image tags + id: metadata + uses: docker/metadata-action@v5 + with: + images: | + name=ghcr.io/${{ github.repository_owner }}/immich-cli + tags: | + type=raw,value=${{ steps.package-version.outputs.version }},enable=${{ github.event_name == 'workflow_dispatch' }} + + - name: Build and push image + uses: docker/build-push-action@v5.1.0 + with: + file: cli/Dockerfile + platforms: linux/amd64,linux/arm64 + push: ${{ github.event_name == 'workflow_dispatch' }} + cache-from: type=gha + cache-to: type=gha,mode=max + tags: ${{ steps.metadata.outputs.tags }} + labels: ${{ steps.metadata.outputs.labels }} From 5088acda107c4096185991d053b89c0b1c266737 Mon Sep 17 00:00:00 2001 From: Alex Date: Thu, 8 Feb 2024 14:00:21 -0600 Subject: [PATCH 045/104] chore: add repo activity to readme (#6982) chore: add repo acvitity to readme --- README.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/README.md b/README.md index 28fe635646..eb55ddbfca 100644 --- a/README.md +++ b/README.md @@ -69,6 +69,9 @@ password: demo Spec: Free-tier Oracle VM - Amsterdam - 2.4Ghz quad-core ARM64 CPU, 24GB RAM ``` +## Activities +![Activities](https://repobeats.axiom.co/api/embed/9e86d9dc3ddd137161f2f6d2e758d7863b1789cb.svg "Repobeats analytics image") + ## Features From bd1fa9377b19b8cef6c19f9ff2a0ddd1aee2f826 Mon Sep 17 00:00:00 2001 From: Jason Rasmussen Date: Thu, 8 Feb 2024 16:56:06 -0500 Subject: [PATCH 046/104] refactor(server): asset core (#6985) refactor: asset core --- .../immich/api-v1/asset/asset-repository.ts | 11 --- server/src/immich/api-v1/asset/asset.core.ts | 67 ---------------- .../immich/api-v1/asset/asset.service.spec.ts | 13 ++-- .../src/immich/api-v1/asset/asset.service.ts | 78 +++++++++++++++---- 4 files changed, 70 insertions(+), 99 deletions(-) delete mode 100644 server/src/immich/api-v1/asset/asset.core.ts diff --git a/server/src/immich/api-v1/asset/asset-repository.ts b/server/src/immich/api-v1/asset/asset-repository.ts index c8b76d9674..7d55fa790e 100644 --- a/server/src/immich/api-v1/asset/asset-repository.ts +++ b/server/src/immich/api-v1/asset/asset-repository.ts @@ -1,4 +1,3 @@ -import { AssetCreate } from '@app/domain'; import { AssetEntity, ExifEntity } from '@app/infra/entities'; import { OptionalBetween } from '@app/infra/infra.utils'; import { Injectable } from '@nestjs/common'; @@ -22,8 +21,6 @@ export interface AssetOwnerCheck extends AssetCheck { export interface IAssetRepositoryV1 { get(id: string): Promise; - create(asset: AssetCreate): Promise; - upsertExif(exif: Partial): Promise; getAllByUserId(userId: string, dto: AssetSearchDto): Promise; getLocationsByUserId(userId: string): Promise; getDetectedObjectsByUserId(userId: string): Promise; @@ -132,14 +129,6 @@ export class AssetRepositoryV1 implements IAssetRepositoryV1 { }); } - create(asset: AssetCreate): Promise { - return this.assetRepository.save(asset); - } - - async upsertExif(exif: Partial): Promise { - await this.exifRepository.upsert(exif, { conflictPaths: ['assetId'] }); - } - /** * Get assets by checksums on the database * @param ownerId diff --git a/server/src/immich/api-v1/asset/asset.core.ts b/server/src/immich/api-v1/asset/asset.core.ts deleted file mode 100644 index 0688a65dd6..0000000000 --- a/server/src/immich/api-v1/asset/asset.core.ts +++ /dev/null @@ -1,67 +0,0 @@ -import { AuthDto, IJobRepository, JobName, mimeTypes, UploadFile } from '@app/domain'; -import { AssetEntity } from '@app/infra/entities'; -import { BadRequestException } from '@nestjs/common'; -import { parse } from 'node:path'; -import { IAssetRepositoryV1 } from './asset-repository'; -import { CreateAssetDto } from './dto/create-asset.dto'; - -export class AssetCore { - constructor( - private repository: IAssetRepositoryV1, - private jobRepository: IJobRepository, - ) {} - - async create( - auth: AuthDto, - dto: CreateAssetDto & { libraryId: string }, - file: UploadFile, - livePhotoAssetId?: string, - sidecarPath?: string, - ): Promise { - const asset = await this.repository.create({ - ownerId: auth.user.id, - libraryId: dto.libraryId, - - checksum: file.checksum, - originalPath: file.originalPath, - - deviceAssetId: dto.deviceAssetId, - deviceId: dto.deviceId, - - fileCreatedAt: dto.fileCreatedAt, - fileModifiedAt: dto.fileModifiedAt, - localDateTime: dto.fileCreatedAt, - deletedAt: null, - - type: mimeTypes.assetType(file.originalPath), - isFavorite: dto.isFavorite, - isArchived: dto.isArchived ?? false, - duration: dto.duration || null, - isVisible: dto.isVisible ?? true, - livePhotoVideo: livePhotoAssetId === null ? null : ({ id: livePhotoAssetId } as AssetEntity), - resizePath: null, - webpPath: null, - thumbhash: null, - encodedVideoPath: null, - tags: [], - sharedLinks: [], - originalFileName: parse(file.originalName).name, - faces: [], - sidecarPath: sidecarPath || null, - isReadOnly: dto.isReadOnly ?? false, - isExternal: dto.isExternal ?? false, - isOffline: dto.isOffline ?? false, - }); - - await this.repository.upsertExif({ assetId: asset.id, fileSizeInByte: file.size }); - await this.jobRepository.queue({ name: JobName.METADATA_EXTRACTION, data: { id: asset.id, source: 'upload' } }); - - return asset; - } - - static requireQuota(auth: AuthDto, size: number) { - if (auth.user.quotaSizeInBytes && auth.user.quotaSizeInBytes < auth.user.quotaUsageInBytes + size) { - throw new BadRequestException('Quota has been exceeded!'); - } - } -} diff --git a/server/src/immich/api-v1/asset/asset.service.spec.ts b/server/src/immich/api-v1/asset/asset.service.spec.ts index d5fde4a625..0e5bafa5f0 100644 --- a/server/src/immich/api-v1/asset/asset.service.spec.ts +++ b/server/src/immich/api-v1/asset/asset.service.spec.ts @@ -68,9 +68,6 @@ describe('AssetService', () => { beforeEach(() => { assetRepositoryMockV1 = { get: jest.fn(), - create: jest.fn(), - upsertExif: jest.fn(), - getAllByUserId: jest.fn(), getDetectedObjectsByUserId: jest.fn(), getLocationsByUserId: jest.fn(), @@ -109,12 +106,12 @@ describe('AssetService', () => { }; const dto = _getCreateAssetDto(); - assetRepositoryMockV1.create.mockResolvedValue(assetEntity); + assetMock.create.mockResolvedValue(assetEntity); accessMock.library.checkOwnerAccess.mockResolvedValue(new Set([dto.libraryId!])); await expect(sut.uploadFile(authStub.user1, dto, file)).resolves.toEqual({ duplicate: false, id: 'id_1' }); - expect(assetRepositoryMockV1.create).toHaveBeenCalled(); + expect(assetMock.create).toHaveBeenCalled(); expect(userMock.updateUsage).toHaveBeenCalledWith(authStub.user1.user.id, file.size); }); @@ -131,7 +128,7 @@ describe('AssetService', () => { const error = new QueryFailedError('', [], new Error('unique key violation')); (error as any).constraint = ASSET_CHECKSUM_CONSTRAINT; - assetRepositoryMockV1.create.mockRejectedValue(error); + assetMock.create.mockRejectedValue(error); assetRepositoryMockV1.getAssetsByChecksums.mockResolvedValue([_getAsset_1()]); accessMock.library.checkOwnerAccess.mockResolvedValue(new Set([dto.libraryId!])); @@ -149,8 +146,8 @@ describe('AssetService', () => { const error = new QueryFailedError('', [], new Error('unique key violation')); (error as any).constraint = ASSET_CHECKSUM_CONSTRAINT; - assetRepositoryMockV1.create.mockResolvedValueOnce(assetStub.livePhotoMotionAsset); - assetRepositoryMockV1.create.mockResolvedValueOnce(assetStub.livePhotoStillAsset); + assetMock.create.mockResolvedValueOnce(assetStub.livePhotoMotionAsset); + assetMock.create.mockResolvedValueOnce(assetStub.livePhotoStillAsset); accessMock.library.checkOwnerAccess.mockResolvedValue(new Set([dto.libraryId!])); await expect( diff --git a/server/src/immich/api-v1/asset/asset.service.ts b/server/src/immich/api-v1/asset/asset.service.ts index 6d59647cbf..6a96bf531b 100644 --- a/server/src/immich/api-v1/asset/asset.service.ts +++ b/server/src/immich/api-v1/asset/asset.service.ts @@ -18,10 +18,16 @@ import { } from '@app/domain'; import { ASSET_CHECKSUM_CONSTRAINT, AssetEntity, AssetType, LibraryType } from '@app/infra/entities'; import { ImmichLogger } from '@app/infra/logger'; -import { Inject, Injectable, InternalServerErrorException, NotFoundException } from '@nestjs/common'; +import { + BadRequestException, + Inject, + Injectable, + InternalServerErrorException, + NotFoundException, +} from '@nestjs/common'; +import { parse } from 'node:path'; import { QueryFailedError } from 'typeorm'; import { IAssetRepositoryV1 } from './asset-repository'; -import { AssetCore } from './asset.core'; import { AssetBulkUploadCheckDto } from './dto/asset-check.dto'; import { AssetSearchDto } from './dto/asset-search.dto'; import { CheckExistingAssetsDto } from './dto/check-existing-assets.dto'; @@ -41,7 +47,6 @@ import { CuratedObjectsResponseDto } from './response-dto/curated-objects-respon @Injectable() export class AssetService { readonly logger = new ImmichLogger(AssetService.name); - private assetCore: AssetCore; private access: AccessCore; constructor( @@ -52,7 +57,6 @@ export class AssetService { @Inject(ILibraryRepository) private libraryRepository: ILibraryRepository, @Inject(IUserRepository) private userRepository: IUserRepository, ) { - this.assetCore = new AssetCore(assetRepositoryV1, jobRepository); this.access = AccessCore.create(accessRepository); } @@ -75,19 +79,13 @@ export class AssetService { try { const libraryId = await this.getLibraryId(auth, dto.libraryId); await this.access.requirePermission(auth, Permission.ASSET_UPLOAD, libraryId); - AssetCore.requireQuota(auth, file.size); + this.requireQuota(auth, file.size); if (livePhotoFile) { const livePhotoDto = { ...dto, assetType: AssetType.VIDEO, isVisible: false, libraryId }; - livePhotoAsset = await this.assetCore.create(auth, livePhotoDto, livePhotoFile); + livePhotoAsset = await this.create(auth, livePhotoDto, livePhotoFile); } - const asset = await this.assetCore.create( - auth, - { ...dto, libraryId }, - file, - livePhotoAsset?.id, - sidecarFile?.originalPath, - ); + const asset = await this.create(auth, { ...dto, libraryId }, file, livePhotoAsset?.id, sidecarFile?.originalPath); await this.userRepository.updateUsage(auth.user.id, (livePhotoFile?.size || 0) + file.size); @@ -317,4 +315,58 @@ export class AssetService { return library.id; } + + private async create( + auth: AuthDto, + dto: CreateAssetDto & { libraryId: string }, + file: UploadFile, + livePhotoAssetId?: string, + sidecarPath?: string, + ): Promise { + const asset = await this.assetRepository.create({ + ownerId: auth.user.id, + libraryId: dto.libraryId, + + checksum: file.checksum, + originalPath: file.originalPath, + + deviceAssetId: dto.deviceAssetId, + deviceId: dto.deviceId, + + fileCreatedAt: dto.fileCreatedAt, + fileModifiedAt: dto.fileModifiedAt, + localDateTime: dto.fileCreatedAt, + deletedAt: null, + + type: mimeTypes.assetType(file.originalPath), + isFavorite: dto.isFavorite, + isArchived: dto.isArchived ?? false, + duration: dto.duration || null, + isVisible: dto.isVisible ?? true, + livePhotoVideo: livePhotoAssetId === null ? null : ({ id: livePhotoAssetId } as AssetEntity), + resizePath: null, + webpPath: null, + thumbhash: null, + encodedVideoPath: null, + tags: [], + sharedLinks: [], + originalFileName: parse(file.originalName).name, + faces: [], + sidecarPath: sidecarPath || null, + isReadOnly: dto.isReadOnly ?? false, + isExternal: dto.isExternal ?? false, + isOffline: dto.isOffline ?? false, + }); + + await this.assetRepository.upsertExif({ assetId: asset.id, fileSizeInByte: file.size }); + await this.jobRepository.queue({ name: JobName.METADATA_EXTRACTION, data: { id: asset.id, source: 'upload' } }); + + return asset; + } + + private requireQuota(auth: AuthDto, size: number) { + if (auth.user.quotaSizeInBytes && auth.user.quotaSizeInBytes < auth.user.quotaUsageInBytes + size) { + throw new BadRequestException('Quota has been exceeded!'); + } + } } From 198e8517e5c4e61bfb9162ae15c81d318681286b Mon Sep 17 00:00:00 2001 From: Manas Adepu <112828012+manasadepu@users.noreply.github.com> Date: Thu, 8 Feb 2024 16:56:19 -0500 Subject: [PATCH 047/104] fix(server): use luxon for deleted date calculation (#6958) * luxon implementation * chore: simplify --------- Co-authored-by: Jason Rasmussen --- server/src/domain/user/user.service.ts | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/server/src/domain/user/user.service.ts b/server/src/domain/user/user.service.ts index 7855b1ed6b..a5b3fb7dc7 100644 --- a/server/src/domain/user/user.service.ts +++ b/server/src/domain/user/user.service.ts @@ -1,6 +1,7 @@ import { UserEntity } from '@app/infra/entities'; import { ImmichLogger } from '@app/infra/logger'; import { BadRequestException, ForbiddenException, Inject, Injectable, NotFoundException } from '@nestjs/common'; +import { DateTime } from 'luxon'; import { randomBytes } from 'node:crypto'; import { AuthDto } from '../auth'; import { CacheControl, ImmichFileResponse } from '../domain.util'; @@ -188,12 +189,7 @@ export class UserService { return false; } - // TODO use luxon for date calculation - const msInDay = 86_400_000; - const msDeleteWait = msInDay * 7; - const msSinceDelete = Date.now() - (Date.parse(user.deletedAt.toString()) || 0); - - return msSinceDelete >= msDeleteWait; + return DateTime.now().minus({ days: 7 }) > DateTime.fromJSDate(user.deletedAt); } private async findOrFail(id: string, options: UserFindOptions) { From 90a7f16817f3416ff3a9406413298590a1602eba Mon Sep 17 00:00:00 2001 From: Jason Rasmussen Date: Thu, 8 Feb 2024 16:57:54 -0500 Subject: [PATCH 048/104] chore(server): remove deprecated endpoints (#6984) * chore: remove deprecated endpoints * chore: open api --- .../services/asset_description.service.dart | 2 +- .../services/image_viewer.service.dart | 8 +- .../services/backup_verification.service.dart | 6 +- .../modules/trash/services/trash.service.dart | 6 +- mobile/lib/shared/services/api.service.dart | 4 + mobile/lib/shared/services/asset.service.dart | 2 +- mobile/lib/shared/services/share.service.dart | 4 +- mobile/openapi/.openapi-generator/FILES | 3 - mobile/openapi/README.md | 9 - mobile/openapi/doc/AssetApi.md | 391 --------- mobile/openapi/doc/OAuthApi.md | 44 - mobile/openapi/doc/OAuthConfigResponseDto.md | 19 - mobile/openapi/lib/api.dart | 1 - mobile/openapi/lib/api/asset_api.dart | 332 -------- mobile/openapi/lib/api/o_auth_api.dart | 52 -- mobile/openapi/lib/api_client.dart | 2 - .../lib/model/o_auth_config_response_dto.dart | 157 ---- mobile/openapi/test/asset_api_test.dart | 37 - mobile/openapi/test/o_auth_api_test.dart | 7 - .../test/o_auth_config_response_dto_test.dart | 47 -- open-api/immich-openapi-specs.json | 348 -------- open-api/typescript-sdk/axios-client/api.ts | 758 ------------------ .../fetch-client/.openapi-generator/FILES | 1 - .../fetch-client/apis/AssetApi.ts | 334 -------- .../fetch-client/apis/OAuthApi.ts | 42 - .../fetch-client/models/index.ts | 1 - server/e2e/api/specs/asset.e2e-spec.ts | 190 ++--- server/e2e/api/specs/download.e2e-spec.ts | 89 ++ server/e2e/client/asset-api.ts | 6 +- server/src/domain/auth/auth.dto.ts | 9 - server/src/domain/auth/auth.service.spec.ts | 21 - server/src/domain/auth/auth.service.ts | 23 - .../system-config/system-config.core.ts | 2 - .../immich/api-v1/asset/asset.controller.ts | 20 +- .../immich/controllers/asset.controller.ts | 88 +- .../immich/controllers/oauth.controller.ts | 8 - 36 files changed, 168 insertions(+), 2905 deletions(-) delete mode 100644 mobile/openapi/doc/OAuthConfigResponseDto.md delete mode 100644 mobile/openapi/lib/model/o_auth_config_response_dto.dart delete mode 100644 mobile/openapi/test/o_auth_config_response_dto_test.dart create mode 100644 server/e2e/api/specs/download.e2e-spec.ts diff --git a/mobile/lib/modules/asset_viewer/services/asset_description.service.dart b/mobile/lib/modules/asset_viewer/services/asset_description.service.dart index 9abf69a93a..09de411e5d 100644 --- a/mobile/lib/modules/asset_viewer/services/asset_description.service.dart +++ b/mobile/lib/modules/asset_viewer/services/asset_description.service.dart @@ -36,7 +36,7 @@ class AssetDescriptionService { Future readLatest(String assetRemoteId, int localExifId) async { final latestAssetFromServer = - await _api.assetApi.getAssetById(assetRemoteId); + await _api.assetApi.getAssetInfo(assetRemoteId); final localExifInfo = await _db.exifInfos.get(localExifId); if (latestAssetFromServer != null && localExifInfo != null) { diff --git a/mobile/lib/modules/asset_viewer/services/image_viewer.service.dart b/mobile/lib/modules/asset_viewer/services/image_viewer.service.dart index 301fbdfe29..db527c6e23 100644 --- a/mobile/lib/modules/asset_viewer/services/image_viewer.service.dart +++ b/mobile/lib/modules/asset_viewer/services/image_viewer.service.dart @@ -25,12 +25,12 @@ class ImageViewerService { // Download LivePhotos image and motion part if (asset.isImage && asset.livePhotoVideoId != null && Platform.isIOS) { var imageResponse = - await _apiService.assetApi.downloadFileOldWithHttpInfo( + await _apiService.downloadApi.downloadFileWithHttpInfo( asset.remoteId!, ); var motionReponse = - await _apiService.assetApi.downloadFileOldWithHttpInfo( + await _apiService.downloadApi.downloadFileWithHttpInfo( asset.livePhotoVideoId!, ); @@ -71,8 +71,8 @@ class ImageViewerService { return entity != null; } else { - var res = await _apiService.assetApi - .downloadFileOldWithHttpInfo(asset.remoteId!); + var res = await _apiService.downloadApi + .downloadFileWithHttpInfo(asset.remoteId!); if (res.statusCode != 200) { _log.severe( diff --git a/mobile/lib/modules/backup/services/backup_verification.service.dart b/mobile/lib/modules/backup/services/backup_verification.service.dart index 1447abe90a..95e3a8d58b 100644 --- a/mobile/lib/modules/backup/services/backup_verification.service.dart +++ b/mobile/lib/modules/backup/services/backup_verification.service.dart @@ -136,7 +136,7 @@ class BackupVerificationService { ExifInfo? exif = remote.exifInfo; if (exif != null && exif.lat != null) return false; if (exif == null || exif.fileSize == null) { - final dto = await apiService.assetApi.getAssetById(remote.remoteId!); + final dto = await apiService.assetApi.getAssetInfo(remote.remoteId!); if (dto != null && dto.exifInfo != null) { exif = ExifInfo.fromDto(dto.exifInfo!); } @@ -165,8 +165,8 @@ class BackupVerificationService { // (skip first few KBs containing metadata) final Uint64List localImage = _fakeDecodeImg(local, await file.readAsBytes()); - final res = await apiService.assetApi - .downloadFileOldWithHttpInfo(remote.remoteId!); + final res = await apiService.downloadApi + .downloadFileWithHttpInfo(remote.remoteId!); final Uint64List remoteImage = _fakeDecodeImg(remote, res.bodyBytes); final eq = const ListEquality().equals(remoteImage, localImage); diff --git a/mobile/lib/modules/trash/services/trash.service.dart b/mobile/lib/modules/trash/services/trash.service.dart index cfcae27653..9a9ff5d0b6 100644 --- a/mobile/lib/modules/trash/services/trash.service.dart +++ b/mobile/lib/modules/trash/services/trash.service.dart @@ -22,7 +22,7 @@ class TrashService { try { List remoteIds = assetList.where((a) => a.isRemote).map((e) => e.remoteId!).toList(); - await _apiService.assetApi.restoreAssetsOld(BulkIdsDto(ids: remoteIds)); + await _apiService.trashApi.restoreAssets(BulkIdsDto(ids: remoteIds)); return true; } catch (error, stack) { _log.severe("Cannot restore assets ${error.toString()}", error, stack); @@ -32,7 +32,7 @@ class TrashService { Future emptyTrash() async { try { - await _apiService.assetApi.emptyTrashOld(); + await _apiService.trashApi.emptyTrash(); } catch (error, stack) { _log.severe("Cannot empty trash ${error.toString()}", error, stack); } @@ -40,7 +40,7 @@ class TrashService { Future restoreTrash() async { try { - await _apiService.assetApi.restoreTrashOld(); + await _apiService.trashApi.restoreTrash(); } catch (error, stack) { _log.severe("Cannot restore trash ${error.toString()}", error, stack); } diff --git a/mobile/lib/shared/services/api.service.dart b/mobile/lib/shared/services/api.service.dart index 2df1ec857f..9e44136fe7 100644 --- a/mobile/lib/shared/services/api.service.dart +++ b/mobile/lib/shared/services/api.service.dart @@ -24,6 +24,8 @@ class ApiService { late SharedLinkApi sharedLinkApi; late SystemConfigApi systemConfigApi; late ActivityApi activityApi; + late DownloadApi downloadApi; + late TrashApi trashApi; ApiService() { final endpoint = Store.tryGet(StoreKey.serverEndpoint); @@ -51,6 +53,8 @@ class ApiService { sharedLinkApi = SharedLinkApi(_apiClient); systemConfigApi = SystemConfigApi(_apiClient); activityApi = ActivityApi(_apiClient); + downloadApi = DownloadApi(_apiClient); + trashApi = TrashApi(_apiClient); } Future resolveAndSetEndpoint(String serverUrl) async { diff --git a/mobile/lib/shared/services/asset.service.dart b/mobile/lib/shared/services/asset.service.dart index 737d4d56ad..48f8c63524 100644 --- a/mobile/lib/shared/services/asset.service.dart +++ b/mobile/lib/shared/services/asset.service.dart @@ -129,7 +129,7 @@ class AssetService { // fileSize is always filled on the server but not set on client if (a.exifInfo?.fileSize == null) { if (a.isRemote) { - final dto = await _apiService.assetApi.getAssetById(a.remoteId!); + final dto = await _apiService.assetApi.getAssetInfo(a.remoteId!); if (dto != null && dto.exifInfo != null) { final newExif = Asset.remote(dto).exifInfo!.copyWith(id: a.id); if (newExif != a.exifInfo) { diff --git a/mobile/lib/shared/services/share.service.dart b/mobile/lib/shared/services/share.service.dart index d503910797..20ee40d588 100644 --- a/mobile/lib/shared/services/share.service.dart +++ b/mobile/lib/shared/services/share.service.dart @@ -31,8 +31,8 @@ class ShareService { final tempDir = await getTemporaryDirectory(); final fileName = asset.fileName; final tempFile = await File('${tempDir.path}/$fileName').create(); - final res = await _apiService.assetApi - .downloadFileOldWithHttpInfo(asset.remoteId!); + final res = await _apiService.downloadApi + .downloadFileWithHttpInfo(asset.remoteId!); if (res.statusCode != 200) { _log.severe( diff --git a/mobile/openapi/.openapi-generator/FILES b/mobile/openapi/.openapi-generator/FILES index 6fc968a491..186e3675c4 100644 --- a/mobile/openapi/.openapi-generator/FILES +++ b/mobile/openapi/.openapi-generator/FILES @@ -95,7 +95,6 @@ doc/OAuthApi.md doc/OAuthAuthorizeResponseDto.md doc/OAuthCallbackDto.md doc/OAuthConfigDto.md -doc/OAuthConfigResponseDto.md doc/PartnerApi.md doc/PartnerResponseDto.md doc/PathEntityType.md @@ -292,7 +291,6 @@ lib/model/model_type.dart lib/model/o_auth_authorize_response_dto.dart lib/model/o_auth_callback_dto.dart lib/model/o_auth_config_dto.dart -lib/model/o_auth_config_response_dto.dart lib/model/partner_response_dto.dart lib/model/path_entity_type.dart lib/model/path_type.dart @@ -462,7 +460,6 @@ test/o_auth_api_test.dart test/o_auth_authorize_response_dto_test.dart test/o_auth_callback_dto_test.dart test/o_auth_config_dto_test.dart -test/o_auth_config_response_dto_test.dart test/partner_api_test.dart test/partner_response_dto_test.dart test/path_entity_type_test.dart diff --git a/mobile/openapi/README.md b/mobile/openapi/README.md index ac05f83b69..3c662af41f 100644 --- a/mobile/openapi/README.md +++ b/mobile/openapi/README.md @@ -94,26 +94,19 @@ Class | Method | HTTP request | Description *AssetApi* | [**checkBulkUpload**](doc//AssetApi.md#checkbulkupload) | **POST** /asset/bulk-upload-check | *AssetApi* | [**checkExistingAssets**](doc//AssetApi.md#checkexistingassets) | **POST** /asset/exist | *AssetApi* | [**deleteAssets**](doc//AssetApi.md#deleteassets) | **DELETE** /asset | -*AssetApi* | [**downloadArchiveOld**](doc//AssetApi.md#downloadarchiveold) | **POST** /asset/download/archive | -*AssetApi* | [**downloadFileOld**](doc//AssetApi.md#downloadfileold) | **POST** /asset/download/{id} | -*AssetApi* | [**emptyTrashOld**](doc//AssetApi.md#emptytrashold) | **POST** /asset/trash/empty | *AssetApi* | [**getAllAssets**](doc//AssetApi.md#getallassets) | **GET** /asset | *AssetApi* | [**getAllUserAssetsByDeviceId**](doc//AssetApi.md#getalluserassetsbydeviceid) | **GET** /asset/device/{deviceId} | -*AssetApi* | [**getAssetById**](doc//AssetApi.md#getassetbyid) | **GET** /asset/assetById/{id} | *AssetApi* | [**getAssetInfo**](doc//AssetApi.md#getassetinfo) | **GET** /asset/{id} | *AssetApi* | [**getAssetSearchTerms**](doc//AssetApi.md#getassetsearchterms) | **GET** /asset/search-terms | *AssetApi* | [**getAssetStatistics**](doc//AssetApi.md#getassetstatistics) | **GET** /asset/statistics | *AssetApi* | [**getAssetThumbnail**](doc//AssetApi.md#getassetthumbnail) | **GET** /asset/thumbnail/{id} | *AssetApi* | [**getCuratedLocations**](doc//AssetApi.md#getcuratedlocations) | **GET** /asset/curated-locations | *AssetApi* | [**getCuratedObjects**](doc//AssetApi.md#getcuratedobjects) | **GET** /asset/curated-objects | -*AssetApi* | [**getDownloadInfoOld**](doc//AssetApi.md#getdownloadinfoold) | **POST** /asset/download/info | *AssetApi* | [**getMapMarkers**](doc//AssetApi.md#getmapmarkers) | **GET** /asset/map-marker | *AssetApi* | [**getMemoryLane**](doc//AssetApi.md#getmemorylane) | **GET** /asset/memory-lane | *AssetApi* | [**getRandom**](doc//AssetApi.md#getrandom) | **GET** /asset/random | *AssetApi* | [**getTimeBucket**](doc//AssetApi.md#gettimebucket) | **GET** /asset/time-bucket | *AssetApi* | [**getTimeBuckets**](doc//AssetApi.md#gettimebuckets) | **GET** /asset/time-buckets | -*AssetApi* | [**restoreAssetsOld**](doc//AssetApi.md#restoreassetsold) | **POST** /asset/restore | -*AssetApi* | [**restoreTrashOld**](doc//AssetApi.md#restoretrashold) | **POST** /asset/trash/restore | *AssetApi* | [**runAssetJobs**](doc//AssetApi.md#runassetjobs) | **POST** /asset/jobs | *AssetApi* | [**searchAssets**](doc//AssetApi.md#searchassets) | **GET** /assets | *AssetApi* | [**serveFile**](doc//AssetApi.md#servefile) | **GET** /asset/file/{id} | @@ -149,7 +142,6 @@ Class | Method | HTTP request | Description *LibraryApi* | [**scanLibrary**](doc//LibraryApi.md#scanlibrary) | **POST** /library/{id}/scan | *LibraryApi* | [**updateLibrary**](doc//LibraryApi.md#updatelibrary) | **PUT** /library/{id} | *OAuthApi* | [**finishOAuth**](doc//OAuthApi.md#finishoauth) | **POST** /oauth/callback | -*OAuthApi* | [**generateOAuthConfig**](doc//OAuthApi.md#generateoauthconfig) | **POST** /oauth/config | *OAuthApi* | [**linkOAuthAccount**](doc//OAuthApi.md#linkoauthaccount) | **POST** /oauth/link | *OAuthApi* | [**redirectOAuthToMobile**](doc//OAuthApi.md#redirectoauthtomobile) | **GET** /oauth/mobile-redirect | *OAuthApi* | [**startOAuth**](doc//OAuthApi.md#startoauth) | **POST** /oauth/authorize | @@ -299,7 +291,6 @@ Class | Method | HTTP request | Description - [OAuthAuthorizeResponseDto](doc//OAuthAuthorizeResponseDto.md) - [OAuthCallbackDto](doc//OAuthCallbackDto.md) - [OAuthConfigDto](doc//OAuthConfigDto.md) - - [OAuthConfigResponseDto](doc//OAuthConfigResponseDto.md) - [PartnerResponseDto](doc//PartnerResponseDto.md) - [PathEntityType](doc//PathEntityType.md) - [PathType](doc//PathType.md) diff --git a/mobile/openapi/doc/AssetApi.md b/mobile/openapi/doc/AssetApi.md index dbff762d30..a7ea1c07c7 100644 --- a/mobile/openapi/doc/AssetApi.md +++ b/mobile/openapi/doc/AssetApi.md @@ -12,26 +12,19 @@ Method | HTTP request | Description [**checkBulkUpload**](AssetApi.md#checkbulkupload) | **POST** /asset/bulk-upload-check | [**checkExistingAssets**](AssetApi.md#checkexistingassets) | **POST** /asset/exist | [**deleteAssets**](AssetApi.md#deleteassets) | **DELETE** /asset | -[**downloadArchiveOld**](AssetApi.md#downloadarchiveold) | **POST** /asset/download/archive | -[**downloadFileOld**](AssetApi.md#downloadfileold) | **POST** /asset/download/{id} | -[**emptyTrashOld**](AssetApi.md#emptytrashold) | **POST** /asset/trash/empty | [**getAllAssets**](AssetApi.md#getallassets) | **GET** /asset | [**getAllUserAssetsByDeviceId**](AssetApi.md#getalluserassetsbydeviceid) | **GET** /asset/device/{deviceId} | -[**getAssetById**](AssetApi.md#getassetbyid) | **GET** /asset/assetById/{id} | [**getAssetInfo**](AssetApi.md#getassetinfo) | **GET** /asset/{id} | [**getAssetSearchTerms**](AssetApi.md#getassetsearchterms) | **GET** /asset/search-terms | [**getAssetStatistics**](AssetApi.md#getassetstatistics) | **GET** /asset/statistics | [**getAssetThumbnail**](AssetApi.md#getassetthumbnail) | **GET** /asset/thumbnail/{id} | [**getCuratedLocations**](AssetApi.md#getcuratedlocations) | **GET** /asset/curated-locations | [**getCuratedObjects**](AssetApi.md#getcuratedobjects) | **GET** /asset/curated-objects | -[**getDownloadInfoOld**](AssetApi.md#getdownloadinfoold) | **POST** /asset/download/info | [**getMapMarkers**](AssetApi.md#getmapmarkers) | **GET** /asset/map-marker | [**getMemoryLane**](AssetApi.md#getmemorylane) | **GET** /asset/memory-lane | [**getRandom**](AssetApi.md#getrandom) | **GET** /asset/random | [**getTimeBucket**](AssetApi.md#gettimebucket) | **GET** /asset/time-bucket | [**getTimeBuckets**](AssetApi.md#gettimebuckets) | **GET** /asset/time-buckets | -[**restoreAssetsOld**](AssetApi.md#restoreassetsold) | **POST** /asset/restore | -[**restoreTrashOld**](AssetApi.md#restoretrashold) | **POST** /asset/trash/restore | [**runAssetJobs**](AssetApi.md#runassetjobs) | **POST** /asset/jobs | [**searchAssets**](AssetApi.md#searchassets) | **GET** /assets | [**serveFile**](AssetApi.md#servefile) | **GET** /asset/file/{id} | @@ -209,170 +202,6 @@ void (empty response body) [[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md) -# **downloadArchiveOld** -> MultipartFile downloadArchiveOld(assetIdsDto, key) - - - -### Example -```dart -import 'package:openapi/api.dart'; -// TODO Configure API key authorization: cookie -//defaultApiClient.getAuthentication('cookie').apiKey = 'YOUR_API_KEY'; -// uncomment below to setup prefix (e.g. Bearer) for API key, if needed -//defaultApiClient.getAuthentication('cookie').apiKeyPrefix = 'Bearer'; -// TODO Configure API key authorization: api_key -//defaultApiClient.getAuthentication('api_key').apiKey = 'YOUR_API_KEY'; -// uncomment below to setup prefix (e.g. Bearer) for API key, if needed -//defaultApiClient.getAuthentication('api_key').apiKeyPrefix = 'Bearer'; -// TODO Configure HTTP Bearer authorization: bearer -// Case 1. Use String Token -//defaultApiClient.getAuthentication('bearer').setAccessToken('YOUR_ACCESS_TOKEN'); -// Case 2. Use Function which generate token. -// String yourTokenGeneratorFunction() { ... } -//defaultApiClient.getAuthentication('bearer').setAccessToken(yourTokenGeneratorFunction); - -final api_instance = AssetApi(); -final assetIdsDto = AssetIdsDto(); // AssetIdsDto | -final key = key_example; // String | - -try { - final result = api_instance.downloadArchiveOld(assetIdsDto, key); - print(result); -} catch (e) { - print('Exception when calling AssetApi->downloadArchiveOld: $e\n'); -} -``` - -### Parameters - -Name | Type | Description | Notes -------------- | ------------- | ------------- | ------------- - **assetIdsDto** | [**AssetIdsDto**](AssetIdsDto.md)| | - **key** | **String**| | [optional] - -### Return type - -[**MultipartFile**](MultipartFile.md) - -### Authorization - -[cookie](../README.md#cookie), [api_key](../README.md#api_key), [bearer](../README.md#bearer) - -### HTTP request headers - - - **Content-Type**: application/json - - **Accept**: application/octet-stream - -[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md) - -# **downloadFileOld** -> MultipartFile downloadFileOld(id, key) - - - -### Example -```dart -import 'package:openapi/api.dart'; -// TODO Configure API key authorization: cookie -//defaultApiClient.getAuthentication('cookie').apiKey = 'YOUR_API_KEY'; -// uncomment below to setup prefix (e.g. Bearer) for API key, if needed -//defaultApiClient.getAuthentication('cookie').apiKeyPrefix = 'Bearer'; -// TODO Configure API key authorization: api_key -//defaultApiClient.getAuthentication('api_key').apiKey = 'YOUR_API_KEY'; -// uncomment below to setup prefix (e.g. Bearer) for API key, if needed -//defaultApiClient.getAuthentication('api_key').apiKeyPrefix = 'Bearer'; -// TODO Configure HTTP Bearer authorization: bearer -// Case 1. Use String Token -//defaultApiClient.getAuthentication('bearer').setAccessToken('YOUR_ACCESS_TOKEN'); -// Case 2. Use Function which generate token. -// String yourTokenGeneratorFunction() { ... } -//defaultApiClient.getAuthentication('bearer').setAccessToken(yourTokenGeneratorFunction); - -final api_instance = AssetApi(); -final id = 38400000-8cf0-11bd-b23e-10b96e4ef00d; // String | -final key = key_example; // String | - -try { - final result = api_instance.downloadFileOld(id, key); - print(result); -} catch (e) { - print('Exception when calling AssetApi->downloadFileOld: $e\n'); -} -``` - -### Parameters - -Name | Type | Description | Notes -------------- | ------------- | ------------- | ------------- - **id** | **String**| | - **key** | **String**| | [optional] - -### Return type - -[**MultipartFile**](MultipartFile.md) - -### Authorization - -[cookie](../README.md#cookie), [api_key](../README.md#api_key), [bearer](../README.md#bearer) - -### HTTP request headers - - - **Content-Type**: Not defined - - **Accept**: application/octet-stream - -[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md) - -# **emptyTrashOld** -> emptyTrashOld() - - - -### Example -```dart -import 'package:openapi/api.dart'; -// TODO Configure API key authorization: cookie -//defaultApiClient.getAuthentication('cookie').apiKey = 'YOUR_API_KEY'; -// uncomment below to setup prefix (e.g. Bearer) for API key, if needed -//defaultApiClient.getAuthentication('cookie').apiKeyPrefix = 'Bearer'; -// TODO Configure API key authorization: api_key -//defaultApiClient.getAuthentication('api_key').apiKey = 'YOUR_API_KEY'; -// uncomment below to setup prefix (e.g. Bearer) for API key, if needed -//defaultApiClient.getAuthentication('api_key').apiKeyPrefix = 'Bearer'; -// TODO Configure HTTP Bearer authorization: bearer -// Case 1. Use String Token -//defaultApiClient.getAuthentication('bearer').setAccessToken('YOUR_ACCESS_TOKEN'); -// Case 2. Use Function which generate token. -// String yourTokenGeneratorFunction() { ... } -//defaultApiClient.getAuthentication('bearer').setAccessToken(yourTokenGeneratorFunction); - -final api_instance = AssetApi(); - -try { - api_instance.emptyTrashOld(); -} catch (e) { - print('Exception when calling AssetApi->emptyTrashOld: $e\n'); -} -``` - -### Parameters -This endpoint does not need any parameter. - -### Return type - -void (empty response body) - -### Authorization - -[cookie](../README.md#cookie), [api_key](../README.md#api_key), [bearer](../README.md#bearer) - -### HTTP request headers - - - **Content-Type**: Not defined - - **Accept**: Not defined - -[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md) - # **getAllAssets** > List getAllAssets(ifNoneMatch, isArchived, isFavorite, skip, take, updatedAfter, updatedBefore, userId) @@ -501,65 +330,6 @@ Name | Type | Description | Notes [[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md) -# **getAssetById** -> AssetResponseDto getAssetById(id, key) - - - -Get a single asset's information - -### Example -```dart -import 'package:openapi/api.dart'; -// TODO Configure API key authorization: cookie -//defaultApiClient.getAuthentication('cookie').apiKey = 'YOUR_API_KEY'; -// uncomment below to setup prefix (e.g. Bearer) for API key, if needed -//defaultApiClient.getAuthentication('cookie').apiKeyPrefix = 'Bearer'; -// TODO Configure API key authorization: api_key -//defaultApiClient.getAuthentication('api_key').apiKey = 'YOUR_API_KEY'; -// uncomment below to setup prefix (e.g. Bearer) for API key, if needed -//defaultApiClient.getAuthentication('api_key').apiKeyPrefix = 'Bearer'; -// TODO Configure HTTP Bearer authorization: bearer -// Case 1. Use String Token -//defaultApiClient.getAuthentication('bearer').setAccessToken('YOUR_ACCESS_TOKEN'); -// Case 2. Use Function which generate token. -// String yourTokenGeneratorFunction() { ... } -//defaultApiClient.getAuthentication('bearer').setAccessToken(yourTokenGeneratorFunction); - -final api_instance = AssetApi(); -final id = 38400000-8cf0-11bd-b23e-10b96e4ef00d; // String | -final key = key_example; // String | - -try { - final result = api_instance.getAssetById(id, key); - print(result); -} catch (e) { - print('Exception when calling AssetApi->getAssetById: $e\n'); -} -``` - -### Parameters - -Name | Type | Description | Notes -------------- | ------------- | ------------- | ------------- - **id** | **String**| | - **key** | **String**| | [optional] - -### Return type - -[**AssetResponseDto**](AssetResponseDto.md) - -### Authorization - -[cookie](../README.md#cookie), [api_key](../README.md#api_key), [bearer](../README.md#bearer) - -### HTTP request headers - - - **Content-Type**: Not defined - - **Accept**: application/json - -[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md) - # **getAssetInfo** > AssetResponseDto getAssetInfo(id, key) @@ -888,63 +658,6 @@ This endpoint does not need any parameter. [[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md) -# **getDownloadInfoOld** -> DownloadResponseDto getDownloadInfoOld(downloadInfoDto, key) - - - -### Example -```dart -import 'package:openapi/api.dart'; -// TODO Configure API key authorization: cookie -//defaultApiClient.getAuthentication('cookie').apiKey = 'YOUR_API_KEY'; -// uncomment below to setup prefix (e.g. Bearer) for API key, if needed -//defaultApiClient.getAuthentication('cookie').apiKeyPrefix = 'Bearer'; -// TODO Configure API key authorization: api_key -//defaultApiClient.getAuthentication('api_key').apiKey = 'YOUR_API_KEY'; -// uncomment below to setup prefix (e.g. Bearer) for API key, if needed -//defaultApiClient.getAuthentication('api_key').apiKeyPrefix = 'Bearer'; -// TODO Configure HTTP Bearer authorization: bearer -// Case 1. Use String Token -//defaultApiClient.getAuthentication('bearer').setAccessToken('YOUR_ACCESS_TOKEN'); -// Case 2. Use Function which generate token. -// String yourTokenGeneratorFunction() { ... } -//defaultApiClient.getAuthentication('bearer').setAccessToken(yourTokenGeneratorFunction); - -final api_instance = AssetApi(); -final downloadInfoDto = DownloadInfoDto(); // DownloadInfoDto | -final key = key_example; // String | - -try { - final result = api_instance.getDownloadInfoOld(downloadInfoDto, key); - print(result); -} catch (e) { - print('Exception when calling AssetApi->getDownloadInfoOld: $e\n'); -} -``` - -### Parameters - -Name | Type | Description | Notes -------------- | ------------- | ------------- | ------------- - **downloadInfoDto** | [**DownloadInfoDto**](DownloadInfoDto.md)| | - **key** | **String**| | [optional] - -### Return type - -[**DownloadResponseDto**](DownloadResponseDto.md) - -### Authorization - -[cookie](../README.md#cookie), [api_key](../README.md#api_key), [bearer](../README.md#bearer) - -### HTTP request headers - - - **Content-Type**: application/json - - **Accept**: application/json - -[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md) - # **getMapMarkers** > List getMapMarkers(fileCreatedAfter, fileCreatedBefore, isArchived, isFavorite) @@ -1266,110 +979,6 @@ Name | Type | Description | Notes [[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md) -# **restoreAssetsOld** -> restoreAssetsOld(bulkIdsDto) - - - -### Example -```dart -import 'package:openapi/api.dart'; -// TODO Configure API key authorization: cookie -//defaultApiClient.getAuthentication('cookie').apiKey = 'YOUR_API_KEY'; -// uncomment below to setup prefix (e.g. Bearer) for API key, if needed -//defaultApiClient.getAuthentication('cookie').apiKeyPrefix = 'Bearer'; -// TODO Configure API key authorization: api_key -//defaultApiClient.getAuthentication('api_key').apiKey = 'YOUR_API_KEY'; -// uncomment below to setup prefix (e.g. Bearer) for API key, if needed -//defaultApiClient.getAuthentication('api_key').apiKeyPrefix = 'Bearer'; -// TODO Configure HTTP Bearer authorization: bearer -// Case 1. Use String Token -//defaultApiClient.getAuthentication('bearer').setAccessToken('YOUR_ACCESS_TOKEN'); -// Case 2. Use Function which generate token. -// String yourTokenGeneratorFunction() { ... } -//defaultApiClient.getAuthentication('bearer').setAccessToken(yourTokenGeneratorFunction); - -final api_instance = AssetApi(); -final bulkIdsDto = BulkIdsDto(); // BulkIdsDto | - -try { - api_instance.restoreAssetsOld(bulkIdsDto); -} catch (e) { - print('Exception when calling AssetApi->restoreAssetsOld: $e\n'); -} -``` - -### Parameters - -Name | Type | Description | Notes -------------- | ------------- | ------------- | ------------- - **bulkIdsDto** | [**BulkIdsDto**](BulkIdsDto.md)| | - -### Return type - -void (empty response body) - -### Authorization - -[cookie](../README.md#cookie), [api_key](../README.md#api_key), [bearer](../README.md#bearer) - -### HTTP request headers - - - **Content-Type**: application/json - - **Accept**: Not defined - -[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md) - -# **restoreTrashOld** -> restoreTrashOld() - - - -### Example -```dart -import 'package:openapi/api.dart'; -// TODO Configure API key authorization: cookie -//defaultApiClient.getAuthentication('cookie').apiKey = 'YOUR_API_KEY'; -// uncomment below to setup prefix (e.g. Bearer) for API key, if needed -//defaultApiClient.getAuthentication('cookie').apiKeyPrefix = 'Bearer'; -// TODO Configure API key authorization: api_key -//defaultApiClient.getAuthentication('api_key').apiKey = 'YOUR_API_KEY'; -// uncomment below to setup prefix (e.g. Bearer) for API key, if needed -//defaultApiClient.getAuthentication('api_key').apiKeyPrefix = 'Bearer'; -// TODO Configure HTTP Bearer authorization: bearer -// Case 1. Use String Token -//defaultApiClient.getAuthentication('bearer').setAccessToken('YOUR_ACCESS_TOKEN'); -// Case 2. Use Function which generate token. -// String yourTokenGeneratorFunction() { ... } -//defaultApiClient.getAuthentication('bearer').setAccessToken(yourTokenGeneratorFunction); - -final api_instance = AssetApi(); - -try { - api_instance.restoreTrashOld(); -} catch (e) { - print('Exception when calling AssetApi->restoreTrashOld: $e\n'); -} -``` - -### Parameters -This endpoint does not need any parameter. - -### Return type - -void (empty response body) - -### Authorization - -[cookie](../README.md#cookie), [api_key](../README.md#api_key), [bearer](../README.md#bearer) - -### HTTP request headers - - - **Content-Type**: Not defined - - **Accept**: Not defined - -[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md) - # **runAssetJobs** > runAssetJobs(assetJobsDto) diff --git a/mobile/openapi/doc/OAuthApi.md b/mobile/openapi/doc/OAuthApi.md index fa6b19df53..ce36f7163a 100644 --- a/mobile/openapi/doc/OAuthApi.md +++ b/mobile/openapi/doc/OAuthApi.md @@ -10,7 +10,6 @@ All URIs are relative to */api* Method | HTTP request | Description ------------- | ------------- | ------------- [**finishOAuth**](OAuthApi.md#finishoauth) | **POST** /oauth/callback | -[**generateOAuthConfig**](OAuthApi.md#generateoauthconfig) | **POST** /oauth/config | [**linkOAuthAccount**](OAuthApi.md#linkoauthaccount) | **POST** /oauth/link | [**redirectOAuthToMobile**](OAuthApi.md#redirectoauthtomobile) | **GET** /oauth/mobile-redirect | [**startOAuth**](OAuthApi.md#startoauth) | **POST** /oauth/authorize | @@ -58,49 +57,6 @@ No authorization required [[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md) -# **generateOAuthConfig** -> OAuthConfigResponseDto generateOAuthConfig(oAuthConfigDto) - - - -@deprecated use feature flags and /oauth/authorize - -### Example -```dart -import 'package:openapi/api.dart'; - -final api_instance = OAuthApi(); -final oAuthConfigDto = OAuthConfigDto(); // OAuthConfigDto | - -try { - final result = api_instance.generateOAuthConfig(oAuthConfigDto); - print(result); -} catch (e) { - print('Exception when calling OAuthApi->generateOAuthConfig: $e\n'); -} -``` - -### Parameters - -Name | Type | Description | Notes -------------- | ------------- | ------------- | ------------- - **oAuthConfigDto** | [**OAuthConfigDto**](OAuthConfigDto.md)| | - -### Return type - -[**OAuthConfigResponseDto**](OAuthConfigResponseDto.md) - -### Authorization - -No authorization required - -### HTTP request headers - - - **Content-Type**: application/json - - **Accept**: application/json - -[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md) - # **linkOAuthAccount** > UserResponseDto linkOAuthAccount(oAuthCallbackDto) diff --git a/mobile/openapi/doc/OAuthConfigResponseDto.md b/mobile/openapi/doc/OAuthConfigResponseDto.md deleted file mode 100644 index 8abc6bb607..0000000000 --- a/mobile/openapi/doc/OAuthConfigResponseDto.md +++ /dev/null @@ -1,19 +0,0 @@ -# openapi.model.OAuthConfigResponseDto - -## Load the model package -```dart -import 'package:openapi/api.dart'; -``` - -## Properties -Name | Type | Description | Notes ------------- | ------------- | ------------- | ------------- -**autoLaunch** | **bool** | | [optional] -**buttonText** | **String** | | [optional] -**enabled** | **bool** | | -**passwordLoginEnabled** | **bool** | | -**url** | **String** | | [optional] - -[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) - - diff --git a/mobile/openapi/lib/api.dart b/mobile/openapi/lib/api.dart index 8b9a320566..48305a9804 100644 --- a/mobile/openapi/lib/api.dart +++ b/mobile/openapi/lib/api.dart @@ -131,7 +131,6 @@ part 'model/model_type.dart'; part 'model/o_auth_authorize_response_dto.dart'; part 'model/o_auth_callback_dto.dart'; part 'model/o_auth_config_dto.dart'; -part 'model/o_auth_config_response_dto.dart'; part 'model/partner_response_dto.dart'; part 'model/path_entity_type.dart'; part 'model/path_type.dart'; diff --git a/mobile/openapi/lib/api/asset_api.dart b/mobile/openapi/lib/api/asset_api.dart index 67127392c6..7f4528c12f 100644 --- a/mobile/openapi/lib/api/asset_api.dart +++ b/mobile/openapi/lib/api/asset_api.dart @@ -159,150 +159,6 @@ class AssetApi { } } - /// Performs an HTTP 'POST /asset/download/archive' operation and returns the [Response]. - /// Parameters: - /// - /// * [AssetIdsDto] assetIdsDto (required): - /// - /// * [String] key: - Future downloadArchiveOldWithHttpInfo(AssetIdsDto assetIdsDto, { String? key, }) async { - // ignore: prefer_const_declarations - final path = r'/asset/download/archive'; - - // ignore: prefer_final_locals - Object? postBody = assetIdsDto; - - final queryParams = []; - final headerParams = {}; - final formParams = {}; - - if (key != null) { - queryParams.addAll(_queryParams('', 'key', key)); - } - - const contentTypes = ['application/json']; - - - return apiClient.invokeAPI( - path, - 'POST', - queryParams, - postBody, - headerParams, - formParams, - contentTypes.isEmpty ? null : contentTypes.first, - ); - } - - /// Parameters: - /// - /// * [AssetIdsDto] assetIdsDto (required): - /// - /// * [String] key: - Future downloadArchiveOld(AssetIdsDto assetIdsDto, { String? key, }) async { - final response = await downloadArchiveOldWithHttpInfo(assetIdsDto, key: key, ); - 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), 'MultipartFile',) as MultipartFile; - - } - return null; - } - - /// Performs an HTTP 'POST /asset/download/{id}' operation and returns the [Response]. - /// Parameters: - /// - /// * [String] id (required): - /// - /// * [String] key: - Future downloadFileOldWithHttpInfo(String id, { String? key, }) async { - // ignore: prefer_const_declarations - final path = r'/asset/download/{id}' - .replaceAll('{id}', id); - - // ignore: prefer_final_locals - Object? postBody; - - final queryParams = []; - final headerParams = {}; - final formParams = {}; - - if (key != null) { - queryParams.addAll(_queryParams('', 'key', key)); - } - - const contentTypes = []; - - - return apiClient.invokeAPI( - path, - 'POST', - queryParams, - postBody, - headerParams, - formParams, - contentTypes.isEmpty ? null : contentTypes.first, - ); - } - - /// Parameters: - /// - /// * [String] id (required): - /// - /// * [String] key: - Future downloadFileOld(String id, { String? key, }) async { - final response = await downloadFileOldWithHttpInfo(id, key: key, ); - 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), 'MultipartFile',) as MultipartFile; - - } - return null; - } - - /// Performs an HTTP 'POST /asset/trash/empty' operation and returns the [Response]. - Future emptyTrashOldWithHttpInfo() async { - // ignore: prefer_const_declarations - final path = r'/asset/trash/empty'; - - // ignore: prefer_final_locals - Object? postBody; - - final queryParams = []; - final headerParams = {}; - final formParams = {}; - - const contentTypes = []; - - - return apiClient.invokeAPI( - path, - 'POST', - queryParams, - postBody, - headerParams, - formParams, - contentTypes.isEmpty ? null : contentTypes.first, - ); - } - - Future emptyTrashOld() async { - final response = await emptyTrashOldWithHttpInfo(); - if (response.statusCode >= HttpStatus.badRequest) { - throw ApiException(response.statusCode, await _decodeBodyBytes(response)); - } - } - /// Get all AssetEntity belong to the user /// /// Note: This method returns the HTTP [Response]. @@ -470,67 +326,6 @@ class AssetApi { return null; } - /// Get a single asset's information - /// - /// Note: This method returns the HTTP [Response]. - /// - /// Parameters: - /// - /// * [String] id (required): - /// - /// * [String] key: - Future getAssetByIdWithHttpInfo(String id, { String? key, }) async { - // ignore: prefer_const_declarations - final path = r'/asset/assetById/{id}' - .replaceAll('{id}', id); - - // ignore: prefer_final_locals - Object? postBody; - - final queryParams = []; - final headerParams = {}; - final formParams = {}; - - if (key != null) { - queryParams.addAll(_queryParams('', 'key', key)); - } - - const contentTypes = []; - - - return apiClient.invokeAPI( - path, - 'GET', - queryParams, - postBody, - headerParams, - formParams, - contentTypes.isEmpty ? null : contentTypes.first, - ); - } - - /// Get a single asset's information - /// - /// Parameters: - /// - /// * [String] id (required): - /// - /// * [String] key: - Future getAssetById(String id, { String? key, }) async { - final response = await getAssetByIdWithHttpInfo(id, key: key, ); - 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), 'AssetResponseDto',) as AssetResponseDto; - - } - return null; - } - /// Performs an HTTP 'GET /asset/{id}' operation and returns the [Response]. /// Parameters: /// @@ -847,61 +642,6 @@ class AssetApi { return null; } - /// Performs an HTTP 'POST /asset/download/info' operation and returns the [Response]. - /// Parameters: - /// - /// * [DownloadInfoDto] downloadInfoDto (required): - /// - /// * [String] key: - Future getDownloadInfoOldWithHttpInfo(DownloadInfoDto downloadInfoDto, { String? key, }) async { - // ignore: prefer_const_declarations - final path = r'/asset/download/info'; - - // ignore: prefer_final_locals - Object? postBody = downloadInfoDto; - - final queryParams = []; - final headerParams = {}; - final formParams = {}; - - if (key != null) { - queryParams.addAll(_queryParams('', 'key', key)); - } - - const contentTypes = ['application/json']; - - - return apiClient.invokeAPI( - path, - 'POST', - queryParams, - postBody, - headerParams, - formParams, - contentTypes.isEmpty ? null : contentTypes.first, - ); - } - - /// Parameters: - /// - /// * [DownloadInfoDto] downloadInfoDto (required): - /// - /// * [String] key: - Future getDownloadInfoOld(DownloadInfoDto downloadInfoDto, { String? key, }) async { - final response = await getDownloadInfoOldWithHttpInfo(downloadInfoDto, key: key, ); - 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), 'DownloadResponseDto',) as DownloadResponseDto; - - } - return null; - } - /// Performs an HTTP 'GET /asset/map-marker' operation and returns the [Response]. /// Parameters: /// @@ -1323,78 +1063,6 @@ class AssetApi { return null; } - /// Performs an HTTP 'POST /asset/restore' operation and returns the [Response]. - /// Parameters: - /// - /// * [BulkIdsDto] bulkIdsDto (required): - Future restoreAssetsOldWithHttpInfo(BulkIdsDto bulkIdsDto,) async { - // ignore: prefer_const_declarations - final path = r'/asset/restore'; - - // ignore: prefer_final_locals - Object? postBody = bulkIdsDto; - - final queryParams = []; - final headerParams = {}; - final formParams = {}; - - const contentTypes = ['application/json']; - - - return apiClient.invokeAPI( - path, - 'POST', - queryParams, - postBody, - headerParams, - formParams, - contentTypes.isEmpty ? null : contentTypes.first, - ); - } - - /// Parameters: - /// - /// * [BulkIdsDto] bulkIdsDto (required): - Future restoreAssetsOld(BulkIdsDto bulkIdsDto,) async { - final response = await restoreAssetsOldWithHttpInfo(bulkIdsDto,); - if (response.statusCode >= HttpStatus.badRequest) { - throw ApiException(response.statusCode, await _decodeBodyBytes(response)); - } - } - - /// Performs an HTTP 'POST /asset/trash/restore' operation and returns the [Response]. - Future restoreTrashOldWithHttpInfo() async { - // ignore: prefer_const_declarations - final path = r'/asset/trash/restore'; - - // ignore: prefer_final_locals - Object? postBody; - - final queryParams = []; - final headerParams = {}; - final formParams = {}; - - const contentTypes = []; - - - return apiClient.invokeAPI( - path, - 'POST', - queryParams, - postBody, - headerParams, - formParams, - contentTypes.isEmpty ? null : contentTypes.first, - ); - } - - Future restoreTrashOld() async { - final response = await restoreTrashOldWithHttpInfo(); - if (response.statusCode >= HttpStatus.badRequest) { - throw ApiException(response.statusCode, await _decodeBodyBytes(response)); - } - } - /// Performs an HTTP 'POST /asset/jobs' operation and returns the [Response]. /// Parameters: /// diff --git a/mobile/openapi/lib/api/o_auth_api.dart b/mobile/openapi/lib/api/o_auth_api.dart index c0d6bc06e0..0337384798 100644 --- a/mobile/openapi/lib/api/o_auth_api.dart +++ b/mobile/openapi/lib/api/o_auth_api.dart @@ -63,58 +63,6 @@ class OAuthApi { return null; } - /// @deprecated use feature flags and /oauth/authorize - /// - /// Note: This method returns the HTTP [Response]. - /// - /// Parameters: - /// - /// * [OAuthConfigDto] oAuthConfigDto (required): - Future generateOAuthConfigWithHttpInfo(OAuthConfigDto oAuthConfigDto,) async { - // ignore: prefer_const_declarations - final path = r'/oauth/config'; - - // ignore: prefer_final_locals - Object? postBody = oAuthConfigDto; - - final queryParams = []; - final headerParams = {}; - final formParams = {}; - - const contentTypes = ['application/json']; - - - return apiClient.invokeAPI( - path, - 'POST', - queryParams, - postBody, - headerParams, - formParams, - contentTypes.isEmpty ? null : contentTypes.first, - ); - } - - /// @deprecated use feature flags and /oauth/authorize - /// - /// Parameters: - /// - /// * [OAuthConfigDto] oAuthConfigDto (required): - Future generateOAuthConfig(OAuthConfigDto oAuthConfigDto,) async { - final response = await generateOAuthConfigWithHttpInfo(oAuthConfigDto,); - 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), 'OAuthConfigResponseDto',) as OAuthConfigResponseDto; - - } - return null; - } - /// Performs an HTTP 'POST /oauth/link' operation and returns the [Response]. /// Parameters: /// diff --git a/mobile/openapi/lib/api_client.dart b/mobile/openapi/lib/api_client.dart index a305ded56a..9643a90424 100644 --- a/mobile/openapi/lib/api_client.dart +++ b/mobile/openapi/lib/api_client.dart @@ -344,8 +344,6 @@ class ApiClient { return OAuthCallbackDto.fromJson(value); case 'OAuthConfigDto': return OAuthConfigDto.fromJson(value); - case 'OAuthConfigResponseDto': - return OAuthConfigResponseDto.fromJson(value); case 'PartnerResponseDto': return PartnerResponseDto.fromJson(value); case 'PathEntityType': diff --git a/mobile/openapi/lib/model/o_auth_config_response_dto.dart b/mobile/openapi/lib/model/o_auth_config_response_dto.dart deleted file mode 100644 index 83fd87b6c8..0000000000 --- a/mobile/openapi/lib/model/o_auth_config_response_dto.dart +++ /dev/null @@ -1,157 +0,0 @@ -// -// AUTO-GENERATED FILE, DO NOT MODIFY! -// -// @dart=2.12 - -// 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 OAuthConfigResponseDto { - /// Returns a new [OAuthConfigResponseDto] instance. - OAuthConfigResponseDto({ - this.autoLaunch, - this.buttonText, - required this.enabled, - required this.passwordLoginEnabled, - this.url, - }); - - /// - /// 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. - /// - bool? autoLaunch; - - /// - /// 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? buttonText; - - bool enabled; - - bool passwordLoginEnabled; - - /// - /// 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? url; - - @override - bool operator ==(Object other) => identical(this, other) || other is OAuthConfigResponseDto && - other.autoLaunch == autoLaunch && - other.buttonText == buttonText && - other.enabled == enabled && - other.passwordLoginEnabled == passwordLoginEnabled && - other.url == url; - - @override - int get hashCode => - // ignore: unnecessary_parenthesis - (autoLaunch == null ? 0 : autoLaunch!.hashCode) + - (buttonText == null ? 0 : buttonText!.hashCode) + - (enabled.hashCode) + - (passwordLoginEnabled.hashCode) + - (url == null ? 0 : url!.hashCode); - - @override - String toString() => 'OAuthConfigResponseDto[autoLaunch=$autoLaunch, buttonText=$buttonText, enabled=$enabled, passwordLoginEnabled=$passwordLoginEnabled, url=$url]'; - - Map toJson() { - final json = {}; - if (this.autoLaunch != null) { - json[r'autoLaunch'] = this.autoLaunch; - } else { - // json[r'autoLaunch'] = null; - } - if (this.buttonText != null) { - json[r'buttonText'] = this.buttonText; - } else { - // json[r'buttonText'] = null; - } - json[r'enabled'] = this.enabled; - json[r'passwordLoginEnabled'] = this.passwordLoginEnabled; - if (this.url != null) { - json[r'url'] = this.url; - } else { - // json[r'url'] = null; - } - return json; - } - - /// Returns a new [OAuthConfigResponseDto] instance and imports its values from - /// [value] if it's a [Map], null otherwise. - // ignore: prefer_constructors_over_static_methods - static OAuthConfigResponseDto? fromJson(dynamic value) { - if (value is Map) { - final json = value.cast(); - - return OAuthConfigResponseDto( - autoLaunch: mapValueOfType(json, r'autoLaunch'), - buttonText: mapValueOfType(json, r'buttonText'), - enabled: mapValueOfType(json, r'enabled')!, - passwordLoginEnabled: mapValueOfType(json, r'passwordLoginEnabled')!, - url: mapValueOfType(json, r'url'), - ); - } - return null; - } - - static List listFromJson(dynamic json, {bool growable = false,}) { - final result = []; - if (json is List && json.isNotEmpty) { - for (final row in json) { - final value = OAuthConfigResponseDto.fromJson(row); - if (value != null) { - result.add(value); - } - } - } - return result.toList(growable: growable); - } - - static Map mapFromJson(dynamic json) { - final map = {}; - if (json is Map && json.isNotEmpty) { - json = json.cast(); // ignore: parameter_assignments - for (final entry in json.entries) { - final value = OAuthConfigResponseDto.fromJson(entry.value); - if (value != null) { - map[entry.key] = value; - } - } - } - return map; - } - - // maps a json object with a list of OAuthConfigResponseDto-objects as value to a dart map - static Map> mapListFromJson(dynamic json, {bool growable = false,}) { - final map = >{}; - if (json is Map && json.isNotEmpty) { - // ignore: parameter_assignments - json = json.cast(); - for (final entry in json.entries) { - map[entry.key] = OAuthConfigResponseDto.listFromJson(entry.value, growable: growable,); - } - } - return map; - } - - /// The list of required keys that must be present in a JSON. - static const requiredKeys = { - 'enabled', - 'passwordLoginEnabled', - }; -} - diff --git a/mobile/openapi/test/asset_api_test.dart b/mobile/openapi/test/asset_api_test.dart index 8d0910f1f0..c34c85466c 100644 --- a/mobile/openapi/test/asset_api_test.dart +++ b/mobile/openapi/test/asset_api_test.dart @@ -36,21 +36,6 @@ void main() { // TODO }); - //Future downloadArchiveOld(AssetIdsDto assetIdsDto, { String key }) async - test('test downloadArchiveOld', () async { - // TODO - }); - - //Future downloadFileOld(String id, { String key }) async - test('test downloadFileOld', () async { - // TODO - }); - - //Future emptyTrashOld() async - test('test emptyTrashOld', () async { - // TODO - }); - // Get all AssetEntity belong to the user // //Future> getAllAssets({ String ifNoneMatch, bool isArchived, bool isFavorite, int skip, int take, DateTime updatedAfter, DateTime updatedBefore, String userId }) async @@ -65,13 +50,6 @@ void main() { // TODO }); - // Get a single asset's information - // - //Future getAssetById(String id, { String key }) async - test('test getAssetById', () async { - // TODO - }); - //Future getAssetInfo(String id, { String key }) async test('test getAssetInfo', () async { // TODO @@ -102,11 +80,6 @@ void main() { // TODO }); - //Future getDownloadInfoOld(DownloadInfoDto downloadInfoDto, { String key }) async - test('test getDownloadInfoOld', () async { - // TODO - }); - //Future> getMapMarkers({ DateTime fileCreatedAfter, DateTime fileCreatedBefore, bool isArchived, bool isFavorite }) async test('test getMapMarkers', () async { // TODO @@ -132,16 +105,6 @@ void main() { // TODO }); - //Future restoreAssetsOld(BulkIdsDto bulkIdsDto) async - test('test restoreAssetsOld', () async { - // TODO - }); - - //Future restoreTrashOld() async - test('test restoreTrashOld', () async { - // TODO - }); - //Future runAssetJobs(AssetJobsDto assetJobsDto) async test('test runAssetJobs', () async { // TODO diff --git a/mobile/openapi/test/o_auth_api_test.dart b/mobile/openapi/test/o_auth_api_test.dart index 52326d423f..055963aaec 100644 --- a/mobile/openapi/test/o_auth_api_test.dart +++ b/mobile/openapi/test/o_auth_api_test.dart @@ -22,13 +22,6 @@ void main() { // TODO }); - // @deprecated use feature flags and /oauth/authorize - // - //Future generateOAuthConfig(OAuthConfigDto oAuthConfigDto) async - test('test generateOAuthConfig', () async { - // TODO - }); - //Future linkOAuthAccount(OAuthCallbackDto oAuthCallbackDto) async test('test linkOAuthAccount', () async { // TODO diff --git a/mobile/openapi/test/o_auth_config_response_dto_test.dart b/mobile/openapi/test/o_auth_config_response_dto_test.dart deleted file mode 100644 index fd10307b31..0000000000 --- a/mobile/openapi/test/o_auth_config_response_dto_test.dart +++ /dev/null @@ -1,47 +0,0 @@ -// -// AUTO-GENERATED FILE, DO NOT MODIFY! -// -// @dart=2.12 - -// 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 - -import 'package:openapi/api.dart'; -import 'package:test/test.dart'; - -// tests for OAuthConfigResponseDto -void main() { - // final instance = OAuthConfigResponseDto(); - - group('test OAuthConfigResponseDto', () { - // bool autoLaunch - test('to test the property `autoLaunch`', () async { - // TODO - }); - - // String buttonText - test('to test the property `buttonText`', () async { - // TODO - }); - - // bool enabled - test('to test the property `enabled`', () async { - // TODO - }); - - // bool passwordLoginEnabled - test('to test the property `passwordLoginEnabled`', () async { - // TODO - }); - - // String url - test('to test the property `url`', () async { - // TODO - }); - - - }); - -} diff --git a/open-api/immich-openapi-specs.json b/open-api/immich-openapi-specs.json index b031456a2a..4c6317c2c2 100644 --- a/open-api/immich-openapi-specs.json +++ b/open-api/immich-openapi-specs.json @@ -1055,58 +1055,6 @@ ] } }, - "/asset/assetById/{id}": { - "get": { - "deprecated": true, - "description": "Get a single asset's information", - "operationId": "getAssetById", - "parameters": [ - { - "name": "id", - "required": true, - "in": "path", - "schema": { - "format": "uuid", - "type": "string" - } - }, - { - "name": "key", - "required": false, - "in": "query", - "schema": { - "type": "string" - } - } - ], - "responses": { - "200": { - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/AssetResponseDto" - } - } - }, - "description": "" - } - }, - "security": [ - { - "bearer": [] - }, - { - "cookie": [] - }, - { - "api_key": [] - } - ], - "tags": [ - "Asset" - ] - } - }, "/asset/bulk-upload-check": { "post": { "description": "Checks if assets exist by checksums", @@ -1265,160 +1213,6 @@ ] } }, - "/asset/download/archive": { - "post": { - "operationId": "downloadArchiveOld", - "parameters": [ - { - "name": "key", - "required": false, - "in": "query", - "schema": { - "type": "string" - } - } - ], - "requestBody": { - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/AssetIdsDto" - } - } - }, - "required": true - }, - "responses": { - "200": { - "content": { - "application/octet-stream": { - "schema": { - "format": "binary", - "type": "string" - } - } - }, - "description": "" - } - }, - "security": [ - { - "bearer": [] - }, - { - "cookie": [] - }, - { - "api_key": [] - } - ], - "tags": [ - "Asset" - ] - } - }, - "/asset/download/info": { - "post": { - "operationId": "getDownloadInfoOld", - "parameters": [ - { - "name": "key", - "required": false, - "in": "query", - "schema": { - "type": "string" - } - } - ], - "requestBody": { - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/DownloadInfoDto" - } - } - }, - "required": true - }, - "responses": { - "201": { - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/DownloadResponseDto" - } - } - }, - "description": "" - } - }, - "security": [ - { - "bearer": [] - }, - { - "cookie": [] - }, - { - "api_key": [] - } - ], - "tags": [ - "Asset" - ] - } - }, - "/asset/download/{id}": { - "post": { - "operationId": "downloadFileOld", - "parameters": [ - { - "name": "id", - "required": true, - "in": "path", - "schema": { - "format": "uuid", - "type": "string" - } - }, - { - "name": "key", - "required": false, - "in": "query", - "schema": { - "type": "string" - } - } - ], - "responses": { - "200": { - "content": { - "application/octet-stream": { - "schema": { - "format": "binary", - "type": "string" - } - } - }, - "description": "" - } - }, - "security": [ - { - "bearer": [] - }, - { - "cookie": [] - }, - { - "api_key": [] - } - ], - "tags": [ - "Asset" - ] - } - }, "/asset/exist": { "post": { "description": "Checks if multiple assets exist on the server and returns all existing - used by background backup", @@ -1732,41 +1526,6 @@ ] } }, - "/asset/restore": { - "post": { - "operationId": "restoreAssetsOld", - "parameters": [], - "requestBody": { - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/BulkIdsDto" - } - } - }, - "required": true - }, - "responses": { - "204": { - "description": "" - } - }, - "security": [ - { - "bearer": [] - }, - { - "cookie": [] - }, - { - "api_key": [] - } - ], - "tags": [ - "Asset" - ] - } - }, "/asset/search-terms": { "get": { "operationId": "getAssetSearchTerms", @@ -2217,56 +1976,6 @@ ] } }, - "/asset/trash/empty": { - "post": { - "operationId": "emptyTrashOld", - "parameters": [], - "responses": { - "204": { - "description": "" - } - }, - "security": [ - { - "bearer": [] - }, - { - "cookie": [] - }, - { - "api_key": [] - } - ], - "tags": [ - "Asset" - ] - } - }, - "/asset/trash/restore": { - "post": { - "operationId": "restoreTrashOld", - "parameters": [], - "responses": { - "204": { - "description": "" - } - }, - "security": [ - { - "bearer": [] - }, - { - "cookie": [] - }, - { - "api_key": [] - } - ], - "tags": [ - "Asset" - ] - } - }, "/asset/upload": { "post": { "operationId": "uploadFile", @@ -3935,39 +3644,6 @@ ] } }, - "/oauth/config": { - "post": { - "deprecated": true, - "description": "@deprecated use feature flags and /oauth/authorize", - "operationId": "generateOAuthConfig", - "parameters": [], - "requestBody": { - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/OAuthConfigDto" - } - } - }, - "required": true - }, - "responses": { - "201": { - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/OAuthConfigResponseDto" - } - } - }, - "description": "" - } - }, - "tags": [ - "OAuth" - ] - } - }, "/oauth/link": { "post": { "operationId": "linkOAuthAccount", @@ -8399,30 +8075,6 @@ ], "type": "object" }, - "OAuthConfigResponseDto": { - "properties": { - "autoLaunch": { - "type": "boolean" - }, - "buttonText": { - "type": "string" - }, - "enabled": { - "type": "boolean" - }, - "passwordLoginEnabled": { - "type": "boolean" - }, - "url": { - "type": "string" - } - }, - "required": [ - "enabled", - "passwordLoginEnabled" - ], - "type": "object" - }, "PartnerResponseDto": { "properties": { "avatarColor": { diff --git a/open-api/typescript-sdk/axios-client/api.ts b/open-api/typescript-sdk/axios-client/api.ts index f8866b7904..542fa0580e 100644 --- a/open-api/typescript-sdk/axios-client/api.ts +++ b/open-api/typescript-sdk/axios-client/api.ts @@ -2383,43 +2383,6 @@ export interface OAuthConfigDto { */ 'redirectUri': string; } -/** - * - * @export - * @interface OAuthConfigResponseDto - */ -export interface OAuthConfigResponseDto { - /** - * - * @type {boolean} - * @memberof OAuthConfigResponseDto - */ - 'autoLaunch'?: boolean; - /** - * - * @type {string} - * @memberof OAuthConfigResponseDto - */ - 'buttonText'?: string; - /** - * - * @type {boolean} - * @memberof OAuthConfigResponseDto - */ - 'enabled': boolean; - /** - * - * @type {boolean} - * @memberof OAuthConfigResponseDto - */ - 'passwordLoginEnabled': boolean; - /** - * - * @type {string} - * @memberof OAuthConfigResponseDto - */ - 'url'?: string; -} /** * * @export @@ -6981,140 +6944,6 @@ export const AssetApiAxiosParamCreator = function (configuration?: Configuration options: localVarRequestOptions, }; }, - /** - * - * @param {AssetIdsDto} assetIdsDto - * @param {string} [key] - * @param {*} [options] Override http request option. - * @throws {RequiredError} - */ - downloadArchiveOld: async (assetIdsDto: AssetIdsDto, key?: string, options: RawAxiosRequestConfig = {}): Promise => { - // verify required parameter 'assetIdsDto' is not null or undefined - assertParamExists('downloadArchiveOld', 'assetIdsDto', assetIdsDto) - const localVarPath = `/asset/download/archive`; - // use dummy base URL string because the URL constructor only accepts absolute URLs. - const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL); - let baseOptions; - if (configuration) { - baseOptions = configuration.baseOptions; - } - - const localVarRequestOptions = { method: 'POST', ...baseOptions, ...options}; - const localVarHeaderParameter = {} as any; - const localVarQueryParameter = {} as any; - - // authentication cookie required - - // authentication api_key required - await setApiKeyToObject(localVarHeaderParameter, "x-api-key", configuration) - - // authentication bearer required - // http bearer authentication required - await setBearerAuthToObject(localVarHeaderParameter, configuration) - - if (key !== undefined) { - localVarQueryParameter['key'] = key; - } - - - - localVarHeaderParameter['Content-Type'] = 'application/json'; - - setSearchParams(localVarUrlObj, localVarQueryParameter); - let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {}; - localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers}; - localVarRequestOptions.data = serializeDataIfNeeded(assetIdsDto, localVarRequestOptions, configuration) - - return { - url: toPathString(localVarUrlObj), - options: localVarRequestOptions, - }; - }, - /** - * - * @param {string} id - * @param {string} [key] - * @param {*} [options] Override http request option. - * @throws {RequiredError} - */ - downloadFileOld: async (id: string, key?: string, options: RawAxiosRequestConfig = {}): Promise => { - // verify required parameter 'id' is not null or undefined - assertParamExists('downloadFileOld', 'id', id) - const localVarPath = `/asset/download/{id}` - .replace(`{${"id"}}`, encodeURIComponent(String(id))); - // use dummy base URL string because the URL constructor only accepts absolute URLs. - const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL); - let baseOptions; - if (configuration) { - baseOptions = configuration.baseOptions; - } - - const localVarRequestOptions = { method: 'POST', ...baseOptions, ...options}; - const localVarHeaderParameter = {} as any; - const localVarQueryParameter = {} as any; - - // authentication cookie required - - // authentication api_key required - await setApiKeyToObject(localVarHeaderParameter, "x-api-key", configuration) - - // authentication bearer required - // http bearer authentication required - await setBearerAuthToObject(localVarHeaderParameter, configuration) - - if (key !== undefined) { - localVarQueryParameter['key'] = key; - } - - - - setSearchParams(localVarUrlObj, localVarQueryParameter); - let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {}; - localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers}; - - return { - url: toPathString(localVarUrlObj), - options: localVarRequestOptions, - }; - }, - /** - * - * @param {*} [options] Override http request option. - * @throws {RequiredError} - */ - emptyTrashOld: async (options: RawAxiosRequestConfig = {}): Promise => { - const localVarPath = `/asset/trash/empty`; - // use dummy base URL string because the URL constructor only accepts absolute URLs. - const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL); - let baseOptions; - if (configuration) { - baseOptions = configuration.baseOptions; - } - - const localVarRequestOptions = { method: 'POST', ...baseOptions, ...options}; - const localVarHeaderParameter = {} as any; - const localVarQueryParameter = {} as any; - - // authentication cookie required - - // authentication api_key required - await setApiKeyToObject(localVarHeaderParameter, "x-api-key", configuration) - - // authentication bearer required - // http bearer authentication required - await setBearerAuthToObject(localVarHeaderParameter, configuration) - - - - setSearchParams(localVarUrlObj, localVarQueryParameter); - let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {}; - localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers}; - - return { - url: toPathString(localVarUrlObj), - options: localVarRequestOptions, - }; - }, /** * Get all AssetEntity belong to the user * @param {string} [ifNoneMatch] ETag of data already cached on the client @@ -7230,54 +7059,6 @@ export const AssetApiAxiosParamCreator = function (configuration?: Configuration - setSearchParams(localVarUrlObj, localVarQueryParameter); - let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {}; - localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers}; - - return { - url: toPathString(localVarUrlObj), - options: localVarRequestOptions, - }; - }, - /** - * Get a single asset\'s information - * @param {string} id - * @param {string} [key] - * @param {*} [options] Override http request option. - * @deprecated - * @throws {RequiredError} - */ - getAssetById: async (id: string, key?: string, options: RawAxiosRequestConfig = {}): Promise => { - // verify required parameter 'id' is not null or undefined - assertParamExists('getAssetById', 'id', id) - const localVarPath = `/asset/assetById/{id}` - .replace(`{${"id"}}`, encodeURIComponent(String(id))); - // use dummy base URL string because the URL constructor only accepts absolute URLs. - const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL); - let baseOptions; - if (configuration) { - baseOptions = configuration.baseOptions; - } - - const localVarRequestOptions = { method: 'GET', ...baseOptions, ...options}; - const localVarHeaderParameter = {} as any; - const localVarQueryParameter = {} as any; - - // authentication cookie required - - // authentication api_key required - await setApiKeyToObject(localVarHeaderParameter, "x-api-key", configuration) - - // authentication bearer required - // http bearer authentication required - await setBearerAuthToObject(localVarHeaderParameter, configuration) - - if (key !== undefined) { - localVarQueryParameter['key'] = key; - } - - - setSearchParams(localVarUrlObj, localVarQueryParameter); let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {}; localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers}; @@ -7553,55 +7334,6 @@ export const AssetApiAxiosParamCreator = function (configuration?: Configuration options: localVarRequestOptions, }; }, - /** - * - * @param {DownloadInfoDto} downloadInfoDto - * @param {string} [key] - * @param {*} [options] Override http request option. - * @throws {RequiredError} - */ - getDownloadInfoOld: async (downloadInfoDto: DownloadInfoDto, key?: string, options: RawAxiosRequestConfig = {}): Promise => { - // verify required parameter 'downloadInfoDto' is not null or undefined - assertParamExists('getDownloadInfoOld', 'downloadInfoDto', downloadInfoDto) - const localVarPath = `/asset/download/info`; - // use dummy base URL string because the URL constructor only accepts absolute URLs. - const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL); - let baseOptions; - if (configuration) { - baseOptions = configuration.baseOptions; - } - - const localVarRequestOptions = { method: 'POST', ...baseOptions, ...options}; - const localVarHeaderParameter = {} as any; - const localVarQueryParameter = {} as any; - - // authentication cookie required - - // authentication api_key required - await setApiKeyToObject(localVarHeaderParameter, "x-api-key", configuration) - - // authentication bearer required - // http bearer authentication required - await setBearerAuthToObject(localVarHeaderParameter, configuration) - - if (key !== undefined) { - localVarQueryParameter['key'] = key; - } - - - - localVarHeaderParameter['Content-Type'] = 'application/json'; - - setSearchParams(localVarUrlObj, localVarQueryParameter); - let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {}; - localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers}; - localVarRequestOptions.data = serializeDataIfNeeded(downloadInfoDto, localVarRequestOptions, configuration) - - return { - url: toPathString(localVarUrlObj), - options: localVarRequestOptions, - }; - }, /** * * @param {string} [fileCreatedAfter] @@ -7937,88 +7669,6 @@ export const AssetApiAxiosParamCreator = function (configuration?: Configuration - setSearchParams(localVarUrlObj, localVarQueryParameter); - let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {}; - localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers}; - - return { - url: toPathString(localVarUrlObj), - options: localVarRequestOptions, - }; - }, - /** - * - * @param {BulkIdsDto} bulkIdsDto - * @param {*} [options] Override http request option. - * @throws {RequiredError} - */ - restoreAssetsOld: async (bulkIdsDto: BulkIdsDto, options: RawAxiosRequestConfig = {}): Promise => { - // verify required parameter 'bulkIdsDto' is not null or undefined - assertParamExists('restoreAssetsOld', 'bulkIdsDto', bulkIdsDto) - const localVarPath = `/asset/restore`; - // use dummy base URL string because the URL constructor only accepts absolute URLs. - const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL); - let baseOptions; - if (configuration) { - baseOptions = configuration.baseOptions; - } - - const localVarRequestOptions = { method: 'POST', ...baseOptions, ...options}; - const localVarHeaderParameter = {} as any; - const localVarQueryParameter = {} as any; - - // authentication cookie required - - // authentication api_key required - await setApiKeyToObject(localVarHeaderParameter, "x-api-key", configuration) - - // authentication bearer required - // http bearer authentication required - await setBearerAuthToObject(localVarHeaderParameter, configuration) - - - - localVarHeaderParameter['Content-Type'] = 'application/json'; - - setSearchParams(localVarUrlObj, localVarQueryParameter); - let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {}; - localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers}; - localVarRequestOptions.data = serializeDataIfNeeded(bulkIdsDto, localVarRequestOptions, configuration) - - return { - url: toPathString(localVarUrlObj), - options: localVarRequestOptions, - }; - }, - /** - * - * @param {*} [options] Override http request option. - * @throws {RequiredError} - */ - restoreTrashOld: async (options: RawAxiosRequestConfig = {}): Promise => { - const localVarPath = `/asset/trash/restore`; - // use dummy base URL string because the URL constructor only accepts absolute URLs. - const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL); - let baseOptions; - if (configuration) { - baseOptions = configuration.baseOptions; - } - - const localVarRequestOptions = { method: 'POST', ...baseOptions, ...options}; - const localVarHeaderParameter = {} as any; - const localVarQueryParameter = {} as any; - - // authentication cookie required - - // authentication api_key required - await setApiKeyToObject(localVarHeaderParameter, "x-api-key", configuration) - - // authentication bearer required - // http bearer authentication required - await setBearerAuthToObject(localVarHeaderParameter, configuration) - - - setSearchParams(localVarUrlObj, localVarQueryParameter); let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {}; localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers}; @@ -8697,43 +8347,6 @@ export const AssetApiFp = function(configuration?: Configuration) { const operationBasePath = operationServerMap['AssetApi.deleteAssets']?.[index]?.url; return (axios, basePath) => createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration)(axios, operationBasePath || basePath); }, - /** - * - * @param {AssetIdsDto} assetIdsDto - * @param {string} [key] - * @param {*} [options] Override http request option. - * @throws {RequiredError} - */ - async downloadArchiveOld(assetIdsDto: AssetIdsDto, key?: string, options?: RawAxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise> { - const localVarAxiosArgs = await localVarAxiosParamCreator.downloadArchiveOld(assetIdsDto, key, options); - const index = configuration?.serverIndex ?? 0; - const operationBasePath = operationServerMap['AssetApi.downloadArchiveOld']?.[index]?.url; - return (axios, basePath) => createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration)(axios, operationBasePath || basePath); - }, - /** - * - * @param {string} id - * @param {string} [key] - * @param {*} [options] Override http request option. - * @throws {RequiredError} - */ - async downloadFileOld(id: string, key?: string, options?: RawAxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise> { - const localVarAxiosArgs = await localVarAxiosParamCreator.downloadFileOld(id, key, options); - const index = configuration?.serverIndex ?? 0; - const operationBasePath = operationServerMap['AssetApi.downloadFileOld']?.[index]?.url; - return (axios, basePath) => createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration)(axios, operationBasePath || basePath); - }, - /** - * - * @param {*} [options] Override http request option. - * @throws {RequiredError} - */ - async emptyTrashOld(options?: RawAxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise> { - const localVarAxiosArgs = await localVarAxiosParamCreator.emptyTrashOld(options); - const index = configuration?.serverIndex ?? 0; - const operationBasePath = operationServerMap['AssetApi.emptyTrashOld']?.[index]?.url; - return (axios, basePath) => createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration)(axios, operationBasePath || basePath); - }, /** * Get all AssetEntity belong to the user * @param {string} [ifNoneMatch] ETag of data already cached on the client @@ -8765,20 +8378,6 @@ export const AssetApiFp = function(configuration?: Configuration) { const operationBasePath = operationServerMap['AssetApi.getAllUserAssetsByDeviceId']?.[index]?.url; return (axios, basePath) => createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration)(axios, operationBasePath || basePath); }, - /** - * Get a single asset\'s information - * @param {string} id - * @param {string} [key] - * @param {*} [options] Override http request option. - * @deprecated - * @throws {RequiredError} - */ - async getAssetById(id: string, key?: string, options?: RawAxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise> { - const localVarAxiosArgs = await localVarAxiosParamCreator.getAssetById(id, key, options); - const index = configuration?.serverIndex ?? 0; - const operationBasePath = operationServerMap['AssetApi.getAssetById']?.[index]?.url; - return (axios, basePath) => createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration)(axios, operationBasePath || basePath); - }, /** * * @param {string} id @@ -8853,19 +8452,6 @@ export const AssetApiFp = function(configuration?: Configuration) { const operationBasePath = operationServerMap['AssetApi.getCuratedObjects']?.[index]?.url; return (axios, basePath) => createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration)(axios, operationBasePath || basePath); }, - /** - * - * @param {DownloadInfoDto} downloadInfoDto - * @param {string} [key] - * @param {*} [options] Override http request option. - * @throws {RequiredError} - */ - async getDownloadInfoOld(downloadInfoDto: DownloadInfoDto, key?: string, options?: RawAxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise> { - const localVarAxiosArgs = await localVarAxiosParamCreator.getDownloadInfoOld(downloadInfoDto, key, options); - const index = configuration?.serverIndex ?? 0; - const operationBasePath = operationServerMap['AssetApi.getDownloadInfoOld']?.[index]?.url; - return (axios, basePath) => createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration)(axios, operationBasePath || basePath); - }, /** * * @param {string} [fileCreatedAfter] @@ -8949,29 +8535,6 @@ export const AssetApiFp = function(configuration?: Configuration) { const operationBasePath = operationServerMap['AssetApi.getTimeBuckets']?.[index]?.url; return (axios, basePath) => createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration)(axios, operationBasePath || basePath); }, - /** - * - * @param {BulkIdsDto} bulkIdsDto - * @param {*} [options] Override http request option. - * @throws {RequiredError} - */ - async restoreAssetsOld(bulkIdsDto: BulkIdsDto, options?: RawAxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise> { - const localVarAxiosArgs = await localVarAxiosParamCreator.restoreAssetsOld(bulkIdsDto, options); - const index = configuration?.serverIndex ?? 0; - const operationBasePath = operationServerMap['AssetApi.restoreAssetsOld']?.[index]?.url; - return (axios, basePath) => createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration)(axios, operationBasePath || basePath); - }, - /** - * - * @param {*} [options] Override http request option. - * @throws {RequiredError} - */ - async restoreTrashOld(options?: RawAxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise> { - const localVarAxiosArgs = await localVarAxiosParamCreator.restoreTrashOld(options); - const index = configuration?.serverIndex ?? 0; - const operationBasePath = operationServerMap['AssetApi.restoreTrashOld']?.[index]?.url; - return (axios, basePath) => createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration)(axios, operationBasePath || basePath); - }, /** * * @param {AssetJobsDto} assetJobsDto @@ -9151,32 +8714,6 @@ export const AssetApiFactory = function (configuration?: Configuration, basePath deleteAssets(requestParameters: AssetApiDeleteAssetsRequest, options?: RawAxiosRequestConfig): AxiosPromise { return localVarFp.deleteAssets(requestParameters.assetBulkDeleteDto, options).then((request) => request(axios, basePath)); }, - /** - * - * @param {AssetApiDownloadArchiveOldRequest} requestParameters Request parameters. - * @param {*} [options] Override http request option. - * @throws {RequiredError} - */ - downloadArchiveOld(requestParameters: AssetApiDownloadArchiveOldRequest, options?: RawAxiosRequestConfig): AxiosPromise { - return localVarFp.downloadArchiveOld(requestParameters.assetIdsDto, requestParameters.key, options).then((request) => request(axios, basePath)); - }, - /** - * - * @param {AssetApiDownloadFileOldRequest} requestParameters Request parameters. - * @param {*} [options] Override http request option. - * @throws {RequiredError} - */ - downloadFileOld(requestParameters: AssetApiDownloadFileOldRequest, options?: RawAxiosRequestConfig): AxiosPromise { - return localVarFp.downloadFileOld(requestParameters.id, requestParameters.key, options).then((request) => request(axios, basePath)); - }, - /** - * - * @param {*} [options] Override http request option. - * @throws {RequiredError} - */ - emptyTrashOld(options?: RawAxiosRequestConfig): AxiosPromise { - return localVarFp.emptyTrashOld(options).then((request) => request(axios, basePath)); - }, /** * Get all AssetEntity belong to the user * @param {AssetApiGetAllAssetsRequest} requestParameters Request parameters. @@ -9195,16 +8732,6 @@ export const AssetApiFactory = function (configuration?: Configuration, basePath getAllUserAssetsByDeviceId(requestParameters: AssetApiGetAllUserAssetsByDeviceIdRequest, options?: RawAxiosRequestConfig): AxiosPromise> { return localVarFp.getAllUserAssetsByDeviceId(requestParameters.deviceId, options).then((request) => request(axios, basePath)); }, - /** - * Get a single asset\'s information - * @param {AssetApiGetAssetByIdRequest} requestParameters Request parameters. - * @param {*} [options] Override http request option. - * @deprecated - * @throws {RequiredError} - */ - getAssetById(requestParameters: AssetApiGetAssetByIdRequest, options?: RawAxiosRequestConfig): AxiosPromise { - return localVarFp.getAssetById(requestParameters.id, requestParameters.key, options).then((request) => request(axios, basePath)); - }, /** * * @param {AssetApiGetAssetInfoRequest} requestParameters Request parameters. @@ -9256,15 +8783,6 @@ export const AssetApiFactory = function (configuration?: Configuration, basePath getCuratedObjects(options?: RawAxiosRequestConfig): AxiosPromise> { return localVarFp.getCuratedObjects(options).then((request) => request(axios, basePath)); }, - /** - * - * @param {AssetApiGetDownloadInfoOldRequest} requestParameters Request parameters. - * @param {*} [options] Override http request option. - * @throws {RequiredError} - */ - getDownloadInfoOld(requestParameters: AssetApiGetDownloadInfoOldRequest, options?: RawAxiosRequestConfig): AxiosPromise { - return localVarFp.getDownloadInfoOld(requestParameters.downloadInfoDto, requestParameters.key, options).then((request) => request(axios, basePath)); - }, /** * * @param {AssetApiGetMapMarkersRequest} requestParameters Request parameters. @@ -9310,23 +8828,6 @@ export const AssetApiFactory = function (configuration?: Configuration, basePath getTimeBuckets(requestParameters: AssetApiGetTimeBucketsRequest, options?: RawAxiosRequestConfig): AxiosPromise> { return localVarFp.getTimeBuckets(requestParameters.size, requestParameters.albumId, requestParameters.isArchived, requestParameters.isFavorite, requestParameters.isTrashed, requestParameters.key, requestParameters.personId, requestParameters.userId, requestParameters.withPartners, requestParameters.withStacked, options).then((request) => request(axios, basePath)); }, - /** - * - * @param {AssetApiRestoreAssetsOldRequest} requestParameters Request parameters. - * @param {*} [options] Override http request option. - * @throws {RequiredError} - */ - restoreAssetsOld(requestParameters: AssetApiRestoreAssetsOldRequest, options?: RawAxiosRequestConfig): AxiosPromise { - return localVarFp.restoreAssetsOld(requestParameters.bulkIdsDto, options).then((request) => request(axios, basePath)); - }, - /** - * - * @param {*} [options] Override http request option. - * @throws {RequiredError} - */ - restoreTrashOld(options?: RawAxiosRequestConfig): AxiosPromise { - return localVarFp.restoreTrashOld(options).then((request) => request(axios, basePath)); - }, /** * * @param {AssetApiRunAssetJobsRequest} requestParameters Request parameters. @@ -9435,48 +8936,6 @@ export interface AssetApiDeleteAssetsRequest { readonly assetBulkDeleteDto: AssetBulkDeleteDto } -/** - * Request parameters for downloadArchiveOld operation in AssetApi. - * @export - * @interface AssetApiDownloadArchiveOldRequest - */ -export interface AssetApiDownloadArchiveOldRequest { - /** - * - * @type {AssetIdsDto} - * @memberof AssetApiDownloadArchiveOld - */ - readonly assetIdsDto: AssetIdsDto - - /** - * - * @type {string} - * @memberof AssetApiDownloadArchiveOld - */ - readonly key?: string -} - -/** - * Request parameters for downloadFileOld operation in AssetApi. - * @export - * @interface AssetApiDownloadFileOldRequest - */ -export interface AssetApiDownloadFileOldRequest { - /** - * - * @type {string} - * @memberof AssetApiDownloadFileOld - */ - readonly id: string - - /** - * - * @type {string} - * @memberof AssetApiDownloadFileOld - */ - readonly key?: string -} - /** * Request parameters for getAllAssets operation in AssetApi. * @export @@ -9554,27 +9013,6 @@ export interface AssetApiGetAllUserAssetsByDeviceIdRequest { readonly deviceId: string } -/** - * Request parameters for getAssetById operation in AssetApi. - * @export - * @interface AssetApiGetAssetByIdRequest - */ -export interface AssetApiGetAssetByIdRequest { - /** - * - * @type {string} - * @memberof AssetApiGetAssetById - */ - readonly id: string - - /** - * - * @type {string} - * @memberof AssetApiGetAssetById - */ - readonly key?: string -} - /** * Request parameters for getAssetInfo operation in AssetApi. * @export @@ -9652,27 +9090,6 @@ export interface AssetApiGetAssetThumbnailRequest { readonly key?: string } -/** - * Request parameters for getDownloadInfoOld operation in AssetApi. - * @export - * @interface AssetApiGetDownloadInfoOldRequest - */ -export interface AssetApiGetDownloadInfoOldRequest { - /** - * - * @type {DownloadInfoDto} - * @memberof AssetApiGetDownloadInfoOld - */ - readonly downloadInfoDto: DownloadInfoDto - - /** - * - * @type {string} - * @memberof AssetApiGetDownloadInfoOld - */ - readonly key?: string -} - /** * Request parameters for getMapMarkers operation in AssetApi. * @export @@ -9904,20 +9321,6 @@ export interface AssetApiGetTimeBucketsRequest { readonly withStacked?: boolean } -/** - * Request parameters for restoreAssetsOld operation in AssetApi. - * @export - * @interface AssetApiRestoreAssetsOldRequest - */ -export interface AssetApiRestoreAssetsOldRequest { - /** - * - * @type {BulkIdsDto} - * @memberof AssetApiRestoreAssetsOld - */ - readonly bulkIdsDto: BulkIdsDto -} - /** * Request parameters for runAssetJobs operation in AssetApi. * @export @@ -10462,38 +9865,6 @@ export class AssetApi extends BaseAPI { return AssetApiFp(this.configuration).deleteAssets(requestParameters.assetBulkDeleteDto, options).then((request) => request(this.axios, this.basePath)); } - /** - * - * @param {AssetApiDownloadArchiveOldRequest} requestParameters Request parameters. - * @param {*} [options] Override http request option. - * @throws {RequiredError} - * @memberof AssetApi - */ - public downloadArchiveOld(requestParameters: AssetApiDownloadArchiveOldRequest, options?: RawAxiosRequestConfig) { - return AssetApiFp(this.configuration).downloadArchiveOld(requestParameters.assetIdsDto, requestParameters.key, options).then((request) => request(this.axios, this.basePath)); - } - - /** - * - * @param {AssetApiDownloadFileOldRequest} requestParameters Request parameters. - * @param {*} [options] Override http request option. - * @throws {RequiredError} - * @memberof AssetApi - */ - public downloadFileOld(requestParameters: AssetApiDownloadFileOldRequest, options?: RawAxiosRequestConfig) { - return AssetApiFp(this.configuration).downloadFileOld(requestParameters.id, requestParameters.key, options).then((request) => request(this.axios, this.basePath)); - } - - /** - * - * @param {*} [options] Override http request option. - * @throws {RequiredError} - * @memberof AssetApi - */ - public emptyTrashOld(options?: RawAxiosRequestConfig) { - return AssetApiFp(this.configuration).emptyTrashOld(options).then((request) => request(this.axios, this.basePath)); - } - /** * Get all AssetEntity belong to the user * @param {AssetApiGetAllAssetsRequest} requestParameters Request parameters. @@ -10516,18 +9887,6 @@ export class AssetApi extends BaseAPI { return AssetApiFp(this.configuration).getAllUserAssetsByDeviceId(requestParameters.deviceId, options).then((request) => request(this.axios, this.basePath)); } - /** - * Get a single asset\'s information - * @param {AssetApiGetAssetByIdRequest} requestParameters Request parameters. - * @param {*} [options] Override http request option. - * @deprecated - * @throws {RequiredError} - * @memberof AssetApi - */ - public getAssetById(requestParameters: AssetApiGetAssetByIdRequest, options?: RawAxiosRequestConfig) { - return AssetApiFp(this.configuration).getAssetById(requestParameters.id, requestParameters.key, options).then((request) => request(this.axios, this.basePath)); - } - /** * * @param {AssetApiGetAssetInfoRequest} requestParameters Request parameters. @@ -10591,17 +9950,6 @@ export class AssetApi extends BaseAPI { return AssetApiFp(this.configuration).getCuratedObjects(options).then((request) => request(this.axios, this.basePath)); } - /** - * - * @param {AssetApiGetDownloadInfoOldRequest} requestParameters Request parameters. - * @param {*} [options] Override http request option. - * @throws {RequiredError} - * @memberof AssetApi - */ - public getDownloadInfoOld(requestParameters: AssetApiGetDownloadInfoOldRequest, options?: RawAxiosRequestConfig) { - return AssetApiFp(this.configuration).getDownloadInfoOld(requestParameters.downloadInfoDto, requestParameters.key, options).then((request) => request(this.axios, this.basePath)); - } - /** * * @param {AssetApiGetMapMarkersRequest} requestParameters Request parameters. @@ -10657,27 +10005,6 @@ export class AssetApi extends BaseAPI { return AssetApiFp(this.configuration).getTimeBuckets(requestParameters.size, requestParameters.albumId, requestParameters.isArchived, requestParameters.isFavorite, requestParameters.isTrashed, requestParameters.key, requestParameters.personId, requestParameters.userId, requestParameters.withPartners, requestParameters.withStacked, options).then((request) => request(this.axios, this.basePath)); } - /** - * - * @param {AssetApiRestoreAssetsOldRequest} requestParameters Request parameters. - * @param {*} [options] Override http request option. - * @throws {RequiredError} - * @memberof AssetApi - */ - public restoreAssetsOld(requestParameters: AssetApiRestoreAssetsOldRequest, options?: RawAxiosRequestConfig) { - return AssetApiFp(this.configuration).restoreAssetsOld(requestParameters.bulkIdsDto, options).then((request) => request(this.axios, this.basePath)); - } - - /** - * - * @param {*} [options] Override http request option. - * @throws {RequiredError} - * @memberof AssetApi - */ - public restoreTrashOld(options?: RawAxiosRequestConfig) { - return AssetApiFp(this.configuration).restoreTrashOld(options).then((request) => request(this.axios, this.basePath)); - } - /** * * @param {AssetApiRunAssetJobsRequest} requestParameters Request parameters. @@ -13391,42 +12718,6 @@ export const OAuthApiAxiosParamCreator = function (configuration?: Configuration options: localVarRequestOptions, }; }, - /** - * @deprecated use feature flags and /oauth/authorize - * @param {OAuthConfigDto} oAuthConfigDto - * @param {*} [options] Override http request option. - * @deprecated - * @throws {RequiredError} - */ - generateOAuthConfig: async (oAuthConfigDto: OAuthConfigDto, options: RawAxiosRequestConfig = {}): Promise => { - // verify required parameter 'oAuthConfigDto' is not null or undefined - assertParamExists('generateOAuthConfig', 'oAuthConfigDto', oAuthConfigDto) - const localVarPath = `/oauth/config`; - // use dummy base URL string because the URL constructor only accepts absolute URLs. - const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL); - let baseOptions; - if (configuration) { - baseOptions = configuration.baseOptions; - } - - const localVarRequestOptions = { method: 'POST', ...baseOptions, ...options}; - const localVarHeaderParameter = {} as any; - const localVarQueryParameter = {} as any; - - - - localVarHeaderParameter['Content-Type'] = 'application/json'; - - setSearchParams(localVarUrlObj, localVarQueryParameter); - let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {}; - localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers}; - localVarRequestOptions.data = serializeDataIfNeeded(oAuthConfigDto, localVarRequestOptions, configuration) - - return { - url: toPathString(localVarUrlObj), - options: localVarRequestOptions, - }; - }, /** * * @param {OAuthCallbackDto} oAuthCallbackDto @@ -13595,19 +12886,6 @@ export const OAuthApiFp = function(configuration?: Configuration) { const operationBasePath = operationServerMap['OAuthApi.finishOAuth']?.[index]?.url; return (axios, basePath) => createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration)(axios, operationBasePath || basePath); }, - /** - * @deprecated use feature flags and /oauth/authorize - * @param {OAuthConfigDto} oAuthConfigDto - * @param {*} [options] Override http request option. - * @deprecated - * @throws {RequiredError} - */ - async generateOAuthConfig(oAuthConfigDto: OAuthConfigDto, options?: RawAxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise> { - const localVarAxiosArgs = await localVarAxiosParamCreator.generateOAuthConfig(oAuthConfigDto, options); - const index = configuration?.serverIndex ?? 0; - const operationBasePath = operationServerMap['OAuthApi.generateOAuthConfig']?.[index]?.url; - return (axios, basePath) => createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration)(axios, operationBasePath || basePath); - }, /** * * @param {OAuthCallbackDto} oAuthCallbackDto @@ -13673,16 +12951,6 @@ export const OAuthApiFactory = function (configuration?: Configuration, basePath finishOAuth(requestParameters: OAuthApiFinishOAuthRequest, options?: RawAxiosRequestConfig): AxiosPromise { return localVarFp.finishOAuth(requestParameters.oAuthCallbackDto, options).then((request) => request(axios, basePath)); }, - /** - * @deprecated use feature flags and /oauth/authorize - * @param {OAuthApiGenerateOAuthConfigRequest} requestParameters Request parameters. - * @param {*} [options] Override http request option. - * @deprecated - * @throws {RequiredError} - */ - generateOAuthConfig(requestParameters: OAuthApiGenerateOAuthConfigRequest, options?: RawAxiosRequestConfig): AxiosPromise { - return localVarFp.generateOAuthConfig(requestParameters.oAuthConfigDto, options).then((request) => request(axios, basePath)); - }, /** * * @param {OAuthApiLinkOAuthAccountRequest} requestParameters Request parameters. @@ -13734,20 +13002,6 @@ export interface OAuthApiFinishOAuthRequest { readonly oAuthCallbackDto: OAuthCallbackDto } -/** - * Request parameters for generateOAuthConfig operation in OAuthApi. - * @export - * @interface OAuthApiGenerateOAuthConfigRequest - */ -export interface OAuthApiGenerateOAuthConfigRequest { - /** - * - * @type {OAuthConfigDto} - * @memberof OAuthApiGenerateOAuthConfig - */ - readonly oAuthConfigDto: OAuthConfigDto -} - /** * Request parameters for linkOAuthAccount operation in OAuthApi. * @export @@ -13794,18 +13048,6 @@ export class OAuthApi extends BaseAPI { return OAuthApiFp(this.configuration).finishOAuth(requestParameters.oAuthCallbackDto, options).then((request) => request(this.axios, this.basePath)); } - /** - * @deprecated use feature flags and /oauth/authorize - * @param {OAuthApiGenerateOAuthConfigRequest} requestParameters Request parameters. - * @param {*} [options] Override http request option. - * @deprecated - * @throws {RequiredError} - * @memberof OAuthApi - */ - public generateOAuthConfig(requestParameters: OAuthApiGenerateOAuthConfigRequest, options?: RawAxiosRequestConfig) { - return OAuthApiFp(this.configuration).generateOAuthConfig(requestParameters.oAuthConfigDto, options).then((request) => request(this.axios, this.basePath)); - } - /** * * @param {OAuthApiLinkOAuthAccountRequest} requestParameters Request parameters. diff --git a/open-api/typescript-sdk/fetch-client/.openapi-generator/FILES b/open-api/typescript-sdk/fetch-client/.openapi-generator/FILES index 3f9fcad44e..404449e74d 100644 --- a/open-api/typescript-sdk/fetch-client/.openapi-generator/FILES +++ b/open-api/typescript-sdk/fetch-client/.openapi-generator/FILES @@ -101,7 +101,6 @@ models/ModelType.ts models/OAuthAuthorizeResponseDto.ts models/OAuthCallbackDto.ts models/OAuthConfigDto.ts -models/OAuthConfigResponseDto.ts models/PartnerResponseDto.ts models/PathEntityType.ts models/PathType.ts diff --git a/open-api/typescript-sdk/fetch-client/apis/AssetApi.ts b/open-api/typescript-sdk/fetch-client/apis/AssetApi.ts index 5d5ea1b170..38f7babb47 100644 --- a/open-api/typescript-sdk/fetch-client/apis/AssetApi.ts +++ b/open-api/typescript-sdk/fetch-client/apis/AssetApi.ts @@ -20,19 +20,15 @@ import type { AssetBulkUploadCheckDto, AssetBulkUploadCheckResponseDto, AssetFileUploadResponseDto, - AssetIdsDto, AssetJobsDto, AssetOrder, AssetResponseDto, AssetStatsResponseDto, AssetTypeEnum, - BulkIdsDto, CheckExistingAssetsDto, CheckExistingAssetsResponseDto, CuratedLocationsResponseDto, CuratedObjectsResponseDto, - DownloadInfoDto, - DownloadResponseDto, MapMarkerResponseDto, MemoryLaneResponseDto, ThumbnailFormat, @@ -52,8 +48,6 @@ import { AssetBulkUploadCheckResponseDtoToJSON, AssetFileUploadResponseDtoFromJSON, AssetFileUploadResponseDtoToJSON, - AssetIdsDtoFromJSON, - AssetIdsDtoToJSON, AssetJobsDtoFromJSON, AssetJobsDtoToJSON, AssetOrderFromJSON, @@ -64,8 +58,6 @@ import { AssetStatsResponseDtoToJSON, AssetTypeEnumFromJSON, AssetTypeEnumToJSON, - BulkIdsDtoFromJSON, - BulkIdsDtoToJSON, CheckExistingAssetsDtoFromJSON, CheckExistingAssetsDtoToJSON, CheckExistingAssetsResponseDtoFromJSON, @@ -74,10 +66,6 @@ import { CuratedLocationsResponseDtoToJSON, CuratedObjectsResponseDtoFromJSON, CuratedObjectsResponseDtoToJSON, - DownloadInfoDtoFromJSON, - DownloadInfoDtoToJSON, - DownloadResponseDtoFromJSON, - DownloadResponseDtoToJSON, MapMarkerResponseDtoFromJSON, MapMarkerResponseDtoToJSON, MemoryLaneResponseDtoFromJSON, @@ -106,16 +94,6 @@ export interface DeleteAssetsRequest { assetBulkDeleteDto: AssetBulkDeleteDto; } -export interface DownloadArchiveOldRequest { - assetIdsDto: AssetIdsDto; - key?: string; -} - -export interface DownloadFileOldRequest { - id: string; - key?: string; -} - export interface GetAllAssetsRequest { ifNoneMatch?: string; isArchived?: boolean; @@ -131,11 +109,6 @@ export interface GetAllUserAssetsByDeviceIdRequest { deviceId: string; } -export interface GetAssetByIdRequest { - id: string; - key?: string; -} - export interface GetAssetInfoRequest { id: string; key?: string; @@ -153,11 +126,6 @@ export interface GetAssetThumbnailRequest { key?: string; } -export interface GetDownloadInfoOldRequest { - downloadInfoDto: DownloadInfoDto; - key?: string; -} - export interface GetMapMarkersRequest { fileCreatedAfter?: Date; fileCreatedBefore?: Date; @@ -201,10 +169,6 @@ export interface GetTimeBucketsRequest { withStacked?: boolean; } -export interface RestoreAssetsOldRequest { - bulkIdsDto: BulkIdsDto; -} - export interface RunAssetJobsRequest { assetJobsDto: AssetJobsDto; } @@ -428,132 +392,6 @@ export class AssetApi extends runtime.BaseAPI { await this.deleteAssetsRaw(requestParameters, initOverrides); } - /** - */ - async downloadArchiveOldRaw(requestParameters: DownloadArchiveOldRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise> { - if (requestParameters.assetIdsDto === null || requestParameters.assetIdsDto === undefined) { - throw new runtime.RequiredError('assetIdsDto','Required parameter requestParameters.assetIdsDto was null or undefined when calling downloadArchiveOld.'); - } - - const queryParameters: any = {}; - - if (requestParameters.key !== undefined) { - queryParameters['key'] = requestParameters.key; - } - - const headerParameters: runtime.HTTPHeaders = {}; - - headerParameters['Content-Type'] = 'application/json'; - - if (this.configuration && this.configuration.apiKey) { - headerParameters["x-api-key"] = this.configuration.apiKey("x-api-key"); // api_key authentication - } - - if (this.configuration && this.configuration.accessToken) { - const token = this.configuration.accessToken; - const tokenString = await token("bearer", []); - - if (tokenString) { - headerParameters["Authorization"] = `Bearer ${tokenString}`; - } - } - const response = await this.request({ - path: `/asset/download/archive`, - method: 'POST', - headers: headerParameters, - query: queryParameters, - body: AssetIdsDtoToJSON(requestParameters.assetIdsDto), - }, initOverrides); - - return new runtime.BlobApiResponse(response); - } - - /** - */ - async downloadArchiveOld(requestParameters: DownloadArchiveOldRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise { - const response = await this.downloadArchiveOldRaw(requestParameters, initOverrides); - return await response.value(); - } - - /** - */ - async downloadFileOldRaw(requestParameters: DownloadFileOldRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise> { - if (requestParameters.id === null || requestParameters.id === undefined) { - throw new runtime.RequiredError('id','Required parameter requestParameters.id was null or undefined when calling downloadFileOld.'); - } - - const queryParameters: any = {}; - - if (requestParameters.key !== undefined) { - queryParameters['key'] = requestParameters.key; - } - - const headerParameters: runtime.HTTPHeaders = {}; - - if (this.configuration && this.configuration.apiKey) { - headerParameters["x-api-key"] = this.configuration.apiKey("x-api-key"); // api_key authentication - } - - if (this.configuration && this.configuration.accessToken) { - const token = this.configuration.accessToken; - const tokenString = await token("bearer", []); - - if (tokenString) { - headerParameters["Authorization"] = `Bearer ${tokenString}`; - } - } - const response = await this.request({ - path: `/asset/download/{id}`.replace(`{${"id"}}`, encodeURIComponent(String(requestParameters.id))), - method: 'POST', - headers: headerParameters, - query: queryParameters, - }, initOverrides); - - return new runtime.BlobApiResponse(response); - } - - /** - */ - async downloadFileOld(requestParameters: DownloadFileOldRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise { - const response = await this.downloadFileOldRaw(requestParameters, initOverrides); - return await response.value(); - } - - /** - */ - async emptyTrashOldRaw(initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise> { - const queryParameters: any = {}; - - const headerParameters: runtime.HTTPHeaders = {}; - - if (this.configuration && this.configuration.apiKey) { - headerParameters["x-api-key"] = this.configuration.apiKey("x-api-key"); // api_key authentication - } - - if (this.configuration && this.configuration.accessToken) { - const token = this.configuration.accessToken; - const tokenString = await token("bearer", []); - - if (tokenString) { - headerParameters["Authorization"] = `Bearer ${tokenString}`; - } - } - const response = await this.request({ - path: `/asset/trash/empty`, - method: 'POST', - headers: headerParameters, - query: queryParameters, - }, initOverrides); - - return new runtime.VoidApiResponse(response); - } - - /** - */ - async emptyTrashOld(initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise { - await this.emptyTrashOldRaw(initOverrides); - } - /** * Get all AssetEntity belong to the user */ @@ -666,54 +504,6 @@ export class AssetApi extends runtime.BaseAPI { return await response.value(); } - /** - * Get a single asset\'s information - * @deprecated - */ - async getAssetByIdRaw(requestParameters: GetAssetByIdRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise> { - if (requestParameters.id === null || requestParameters.id === undefined) { - throw new runtime.RequiredError('id','Required parameter requestParameters.id was null or undefined when calling getAssetById.'); - } - - const queryParameters: any = {}; - - if (requestParameters.key !== undefined) { - queryParameters['key'] = requestParameters.key; - } - - const headerParameters: runtime.HTTPHeaders = {}; - - if (this.configuration && this.configuration.apiKey) { - headerParameters["x-api-key"] = this.configuration.apiKey("x-api-key"); // api_key authentication - } - - if (this.configuration && this.configuration.accessToken) { - const token = this.configuration.accessToken; - const tokenString = await token("bearer", []); - - if (tokenString) { - headerParameters["Authorization"] = `Bearer ${tokenString}`; - } - } - const response = await this.request({ - path: `/asset/assetById/{id}`.replace(`{${"id"}}`, encodeURIComponent(String(requestParameters.id))), - method: 'GET', - headers: headerParameters, - query: queryParameters, - }, initOverrides); - - return new runtime.JSONApiResponse(response, (jsonValue) => AssetResponseDtoFromJSON(jsonValue)); - } - - /** - * Get a single asset\'s information - * @deprecated - */ - async getAssetById(requestParameters: GetAssetByIdRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise { - const response = await this.getAssetByIdRaw(requestParameters, initOverrides); - return await response.value(); - } - /** */ async getAssetInfoRaw(requestParameters: GetAssetInfoRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise> { @@ -962,53 +752,6 @@ export class AssetApi extends runtime.BaseAPI { return await response.value(); } - /** - */ - async getDownloadInfoOldRaw(requestParameters: GetDownloadInfoOldRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise> { - if (requestParameters.downloadInfoDto === null || requestParameters.downloadInfoDto === undefined) { - throw new runtime.RequiredError('downloadInfoDto','Required parameter requestParameters.downloadInfoDto was null or undefined when calling getDownloadInfoOld.'); - } - - const queryParameters: any = {}; - - if (requestParameters.key !== undefined) { - queryParameters['key'] = requestParameters.key; - } - - const headerParameters: runtime.HTTPHeaders = {}; - - headerParameters['Content-Type'] = 'application/json'; - - if (this.configuration && this.configuration.apiKey) { - headerParameters["x-api-key"] = this.configuration.apiKey("x-api-key"); // api_key authentication - } - - if (this.configuration && this.configuration.accessToken) { - const token = this.configuration.accessToken; - const tokenString = await token("bearer", []); - - if (tokenString) { - headerParameters["Authorization"] = `Bearer ${tokenString}`; - } - } - const response = await this.request({ - path: `/asset/download/info`, - method: 'POST', - headers: headerParameters, - query: queryParameters, - body: DownloadInfoDtoToJSON(requestParameters.downloadInfoDto), - }, initOverrides); - - return new runtime.JSONApiResponse(response, (jsonValue) => DownloadResponseDtoFromJSON(jsonValue)); - } - - /** - */ - async getDownloadInfoOld(requestParameters: GetDownloadInfoOldRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise { - const response = await this.getDownloadInfoOldRaw(requestParameters, initOverrides); - return await response.value(); - } - /** */ async getMapMarkersRaw(requestParameters: GetMapMarkersRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise>> { @@ -1321,83 +1064,6 @@ export class AssetApi extends runtime.BaseAPI { return await response.value(); } - /** - */ - async restoreAssetsOldRaw(requestParameters: RestoreAssetsOldRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise> { - if (requestParameters.bulkIdsDto === null || requestParameters.bulkIdsDto === undefined) { - throw new runtime.RequiredError('bulkIdsDto','Required parameter requestParameters.bulkIdsDto was null or undefined when calling restoreAssetsOld.'); - } - - const queryParameters: any = {}; - - const headerParameters: runtime.HTTPHeaders = {}; - - headerParameters['Content-Type'] = 'application/json'; - - if (this.configuration && this.configuration.apiKey) { - headerParameters["x-api-key"] = this.configuration.apiKey("x-api-key"); // api_key authentication - } - - if (this.configuration && this.configuration.accessToken) { - const token = this.configuration.accessToken; - const tokenString = await token("bearer", []); - - if (tokenString) { - headerParameters["Authorization"] = `Bearer ${tokenString}`; - } - } - const response = await this.request({ - path: `/asset/restore`, - method: 'POST', - headers: headerParameters, - query: queryParameters, - body: BulkIdsDtoToJSON(requestParameters.bulkIdsDto), - }, initOverrides); - - return new runtime.VoidApiResponse(response); - } - - /** - */ - async restoreAssetsOld(requestParameters: RestoreAssetsOldRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise { - await this.restoreAssetsOldRaw(requestParameters, initOverrides); - } - - /** - */ - async restoreTrashOldRaw(initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise> { - const queryParameters: any = {}; - - const headerParameters: runtime.HTTPHeaders = {}; - - if (this.configuration && this.configuration.apiKey) { - headerParameters["x-api-key"] = this.configuration.apiKey("x-api-key"); // api_key authentication - } - - if (this.configuration && this.configuration.accessToken) { - const token = this.configuration.accessToken; - const tokenString = await token("bearer", []); - - if (tokenString) { - headerParameters["Authorization"] = `Bearer ${tokenString}`; - } - } - const response = await this.request({ - path: `/asset/trash/restore`, - method: 'POST', - headers: headerParameters, - query: queryParameters, - }, initOverrides); - - return new runtime.VoidApiResponse(response); - } - - /** - */ - async restoreTrashOld(initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise { - await this.restoreTrashOldRaw(initOverrides); - } - /** */ async runAssetJobsRaw(requestParameters: RunAssetJobsRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise> { diff --git a/open-api/typescript-sdk/fetch-client/apis/OAuthApi.ts b/open-api/typescript-sdk/fetch-client/apis/OAuthApi.ts index 60e30d4e0c..295ebbebfd 100644 --- a/open-api/typescript-sdk/fetch-client/apis/OAuthApi.ts +++ b/open-api/typescript-sdk/fetch-client/apis/OAuthApi.ts @@ -19,7 +19,6 @@ import type { OAuthAuthorizeResponseDto, OAuthCallbackDto, OAuthConfigDto, - OAuthConfigResponseDto, UserResponseDto, } from '../models/index'; import { @@ -31,8 +30,6 @@ import { OAuthCallbackDtoToJSON, OAuthConfigDtoFromJSON, OAuthConfigDtoToJSON, - OAuthConfigResponseDtoFromJSON, - OAuthConfigResponseDtoToJSON, UserResponseDtoFromJSON, UserResponseDtoToJSON, } from '../models/index'; @@ -41,10 +38,6 @@ export interface FinishOAuthRequest { oAuthCallbackDto: OAuthCallbackDto; } -export interface GenerateOAuthConfigRequest { - oAuthConfigDto: OAuthConfigDto; -} - export interface LinkOAuthAccountRequest { oAuthCallbackDto: OAuthCallbackDto; } @@ -89,41 +82,6 @@ export class OAuthApi extends runtime.BaseAPI { return await response.value(); } - /** - * @deprecated use feature flags and /oauth/authorize - * @deprecated - */ - async generateOAuthConfigRaw(requestParameters: GenerateOAuthConfigRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise> { - if (requestParameters.oAuthConfigDto === null || requestParameters.oAuthConfigDto === undefined) { - throw new runtime.RequiredError('oAuthConfigDto','Required parameter requestParameters.oAuthConfigDto was null or undefined when calling generateOAuthConfig.'); - } - - const queryParameters: any = {}; - - const headerParameters: runtime.HTTPHeaders = {}; - - headerParameters['Content-Type'] = 'application/json'; - - const response = await this.request({ - path: `/oauth/config`, - method: 'POST', - headers: headerParameters, - query: queryParameters, - body: OAuthConfigDtoToJSON(requestParameters.oAuthConfigDto), - }, initOverrides); - - return new runtime.JSONApiResponse(response, (jsonValue) => OAuthConfigResponseDtoFromJSON(jsonValue)); - } - - /** - * @deprecated use feature flags and /oauth/authorize - * @deprecated - */ - async generateOAuthConfig(requestParameters: GenerateOAuthConfigRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise { - const response = await this.generateOAuthConfigRaw(requestParameters, initOverrides); - return await response.value(); - } - /** */ async linkOAuthAccountRaw(requestParameters: LinkOAuthAccountRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise> { diff --git a/open-api/typescript-sdk/fetch-client/models/index.ts b/open-api/typescript-sdk/fetch-client/models/index.ts index ce30d3afe8..19e4f387fe 100644 --- a/open-api/typescript-sdk/fetch-client/models/index.ts +++ b/open-api/typescript-sdk/fetch-client/models/index.ts @@ -81,7 +81,6 @@ export * from './ModelType'; export * from './OAuthAuthorizeResponseDto'; export * from './OAuthCallbackDto'; export * from './OAuthConfigDto'; -export * from './OAuthConfigResponseDto'; export * from './PartnerResponseDto'; export * from './PathEntityType'; export * from './PathType'; diff --git a/server/e2e/api/specs/asset.e2e-spec.ts b/server/e2e/api/specs/asset.e2e-spec.ts index e38f08d0ca..6f6bc88903 100644 --- a/server/e2e/api/specs/asset.e2e-spec.ts +++ b/server/e2e/api/specs/asset.e2e-spec.ts @@ -14,7 +14,7 @@ import { AssetEntity, AssetStackEntity, AssetType, SharedLinkType } from '@app/i import { AssetRepository } from '@app/infra/repositories'; import { INestApplication } from '@nestjs/common'; import { errorStub, userDto, uuidStub } from '@test/fixtures'; -import { randomBytes } from 'crypto'; +import { randomBytes } from 'node:crypto'; import request from 'supertest'; import { api } from '../../client'; import { generateAsset, testApp, today, yesterday } from '../utils'; @@ -517,91 +517,6 @@ describe(`${AssetController.name} (e2e)`, () => { } }); - // TODO remove with deprecated endpoint - describe('GET /asset/assetById/:id', () => { - it('should require authentication', async () => { - const { status, body } = await request(server).get(`/asset/assetById/${uuidStub.notFound}`); - expect(body).toEqual(errorStub.unauthorized); - expect(status).toBe(401); - }); - - it('should require a valid id', async () => { - const { status, body } = await request(server) - .get(`/asset/assetById/${uuidStub.invalid}`) - .set('Authorization', `Bearer ${user1.accessToken}`); - expect(status).toBe(400); - expect(body).toEqual(errorStub.badRequest(['id must be a UUID'])); - }); - - it('should require access', async () => { - const { status, body } = await request(server) - .get(`/asset/assetById/${asset4.id}`) - .set('Authorization', `Bearer ${user1.accessToken}`); - expect(status).toBe(400); - expect(body).toEqual(errorStub.noPermission); - }); - - it('should get the asset info', async () => { - const { status, body } = await request(server) - .get(`/asset/assetById/${asset1.id}`) - .set('Authorization', `Bearer ${user1.accessToken}`); - expect(status).toBe(200); - expect(body).toMatchObject({ id: asset1.id }); - }); - - it('should work with a shared link', async () => { - const sharedLink = await api.sharedLinkApi.create(server, user1.accessToken, { - type: SharedLinkType.INDIVIDUAL, - assetIds: [asset1.id], - }); - - const { status, body } = await request(server).get(`/asset/assetById/${asset1.id}?key=${sharedLink.key}`); - expect(status).toBe(200); - expect(body).toMatchObject({ id: asset1.id }); - }); - - it('should not send people data for shared links for un-authenticated users', async () => { - const personRepository = app.get(IPersonRepository); - const person = await personRepository.create({ ownerId: asset1.ownerId, name: 'Test Person' }); - - await personRepository.createFaces([ - { - assetId: asset1.id, - personId: person.id, - embedding: Array.from({ length: 512 }, Math.random), - }, - ]); - - const { status, body } = await request(server) - .put(`/asset/${asset1.id}`) - .set('Authorization', `Bearer ${user1.accessToken}`) - .send({ isFavorite: true }); - expect(status).toEqual(200); - expect(body).toMatchObject({ - id: asset1.id, - isFavorite: true, - people: [ - { - birthDate: null, - id: expect.any(String), - isHidden: false, - name: 'Test Person', - thumbnailPath: '', - }, - ], - }); - - const sharedLink = await api.sharedLinkApi.create(server, user1.accessToken, { - type: SharedLinkType.INDIVIDUAL, - assetIds: [asset1.id], - }); - - const data = await request(server).get(`/asset/assetById/${asset1.id}?key=${sharedLink.key}`); - expect(data.status).toBe(200); - expect(data.body).toMatchObject({ people: [] }); - }); - }); - describe('GET /asset/:id', () => { it('should require authentication', async () => { const { status, body } = await request(server).get(`/asset/${uuidStub.notFound}`); @@ -643,6 +558,47 @@ describe(`${AssetController.name} (e2e)`, () => { expect(status).toBe(200); expect(body).toMatchObject({ id: asset1.id }); }); + + it('should not send people data for shared links for un-authenticated users', async () => { + const personRepository = app.get(IPersonRepository); + const person = await personRepository.create({ ownerId: asset1.ownerId, name: 'Test Person' }); + + await personRepository.createFaces([ + { + assetId: asset1.id, + personId: person.id, + embedding: Array.from({ length: 512 }, Math.random), + }, + ]); + + const { status, body } = await request(server) + .put(`/asset/${asset1.id}`) + .set('Authorization', `Bearer ${user1.accessToken}`) + .send({ isFavorite: true }); + expect(status).toEqual(200); + expect(body).toMatchObject({ + id: asset1.id, + isFavorite: true, + people: [ + { + birthDate: null, + id: expect.any(String), + isHidden: false, + name: 'Test Person', + thumbnailPath: '', + }, + ], + }); + + const sharedLink = await api.sharedLinkApi.create(server, user1.accessToken, { + type: SharedLinkType.INDIVIDUAL, + assetIds: [asset1.id], + }); + + const data = await request(server).get(`/asset/${asset1.id}?key=${sharedLink.key}`); + expect(data.status).toBe(200); + expect(data.body).toMatchObject({ people: [] }); + }); }); describe('POST /asset/upload', () => { @@ -920,46 +876,6 @@ describe(`${AssetController.name} (e2e)`, () => { }); }); - describe('POST /asset/download/info', () => { - it('should require authentication', async () => { - const { status, body } = await request(server) - .post(`/asset/download/info`) - .send({ assetIds: [asset1.id] }); - - expect(status).toBe(401); - expect(body).toEqual(errorStub.unauthorized); - }); - - it('should download info', async () => { - const { status, body } = await request(server) - .post('/asset/download/info') - .set('Authorization', `Bearer ${user1.accessToken}`) - .send({ assetIds: [asset1.id] }); - - expect(status).toBe(201); - expect(body).toEqual(expect.objectContaining({ archives: [expect.objectContaining({ assetIds: [asset1.id] })] })); - }); - }); - - describe('POST /asset/download/:id', () => { - it('should require authentication', async () => { - const { status, body } = await request(server).post(`/asset/download/${asset1.id}`); - - expect(status).toBe(401); - expect(body).toEqual(errorStub.unauthorized); - }); - - it('should download file', async () => { - const asset = await api.assetApi.upload(server, user1.accessToken, 'example'); - const response = await request(server) - .post(`/asset/download/${asset.id}`) - .set('Authorization', `Bearer ${user1.accessToken}`); - - expect(response.status).toBe(200); - expect(response.headers['content-type']).toEqual('image/jpeg'); - }); - }); - describe('GET /asset/statistics', () => { beforeEach(async () => { await api.assetApi.upload(server, user1.accessToken, 'favored_asset', { isFavorite: true }); @@ -1459,20 +1375,20 @@ describe(`${AssetController.name} (e2e)`, () => { }); }); + const getAssetIdsWithoutFaces = async () => { + const assetPagination = usePagination(10, (pagination) => + assetRepository.getWithout(pagination, WithoutProperty.FACES), + ); + let assets: AssetEntity[] = []; + for await (const assetsPage of assetPagination) { + assets = [...assets, ...assetsPage]; + } + return assets.map((a) => a.id); + }; + describe(AssetRepository.name, () => { describe('getWithout', () => { describe('WithoutProperty.FACES', () => { - const getAssetIdsWithoutFaces = async () => { - const assetPagination = usePagination(10, (pagination) => - assetRepository.getWithout(pagination, WithoutProperty.FACES), - ); - let assets: AssetEntity[] = []; - for await (const assetsPage of assetPagination) { - assets = [...assets, ...assetsPage]; - } - return assets.map((a) => a.id); - }; - beforeEach(async () => { await assetRepository.save({ id: asset1.id, resizePath: '/path/to/resize' }); expect(await getAssetIdsWithoutFaces()).toContain(asset1.id); diff --git a/server/e2e/api/specs/download.e2e-spec.ts b/server/e2e/api/specs/download.e2e-spec.ts new file mode 100644 index 0000000000..9f8c477df9 --- /dev/null +++ b/server/e2e/api/specs/download.e2e-spec.ts @@ -0,0 +1,89 @@ +import { AssetResponseDto, IAssetRepository, LibraryResponseDto, LoginResponseDto, mapAsset } from '@app/domain'; +import { AssetController } from '@app/immich'; +import { AssetEntity } from '@app/infra/entities'; +import { INestApplication } from '@nestjs/common'; +import { errorStub, userDto } from '@test/fixtures'; +import request from 'supertest'; +import { api } from '../../client'; +import { generateAsset, testApp } from '../utils'; + +describe(`${AssetController.name} (e2e)`, () => { + let app: INestApplication; + let server: any; + let assetRepository: IAssetRepository; + let user1: LoginResponseDto; + let libraries: LibraryResponseDto[]; + let asset1: AssetResponseDto; + + const createAsset = async ( + loginResponse: LoginResponseDto, + fileCreatedAt: Date, + other: Partial = {}, + ) => { + const asset = await assetRepository.create( + generateAsset(loginResponse.userId, libraries, { fileCreatedAt, ...other }), + ); + + return mapAsset(asset); + }; + + beforeAll(async () => { + app = await testApp.create(); + server = app.getHttpServer(); + assetRepository = app.get(IAssetRepository); + + await testApp.reset(); + + await api.authApi.adminSignUp(server); + const admin = await api.authApi.adminLogin(server); + + await api.userApi.create(server, admin.accessToken, userDto.user1); + user1 = await api.authApi.login(server, userDto.user1); + libraries = await api.libraryApi.getAll(server, user1.accessToken); + asset1 = await createAsset(user1, new Date('1970-01-01')); + }); + + afterAll(async () => { + await testApp.teardown(); + }); + + describe('POST /download/info', () => { + it('should require authentication', async () => { + const { status, body } = await request(server) + .post(`/download/info`) + .send({ assetIds: [asset1.id] }); + + expect(status).toBe(401); + expect(body).toEqual(errorStub.unauthorized); + }); + + it('should download info', async () => { + const { status, body } = await request(server) + .post('/download/info') + .set('Authorization', `Bearer ${user1.accessToken}`) + .send({ assetIds: [asset1.id] }); + + expect(status).toBe(201); + expect(body).toEqual(expect.objectContaining({ archives: [expect.objectContaining({ assetIds: [asset1.id] })] })); + }); + }); + + describe('POST /download/asset/:id', () => { + it('should require authentication', async () => { + const { status, body } = await request(server).post(`/download/asset/${asset1.id}`); + + expect(status).toBe(401); + expect(body).toEqual(errorStub.unauthorized); + }); + + it('should download file', async () => { + const asset = await api.assetApi.upload(server, user1.accessToken, 'example'); + const response = await request(server) + .post(`/download/asset/${asset.id}`) + .set('Authorization', `Bearer ${user1.accessToken}`); + + expect(response.status).toBe(200); + expect(response.headers['content-type']).toEqual('image/jpeg'); + }); + }); +}); diff --git a/server/e2e/client/asset-api.ts b/server/e2e/client/asset-api.ts index b9ae897b33..8d2a1b79bc 100644 --- a/server/e2e/client/asset-api.ts +++ b/server/e2e/client/asset-api.ts @@ -1,7 +1,7 @@ import { AssetResponseDto } from '@app/domain'; import { CreateAssetDto } from '@app/immich/api-v1/asset/dto/create-asset.dto'; import { AssetFileUploadResponseDto } from '@app/immich/api-v1/asset/response-dto/asset-file-upload-response.dto'; -import { randomBytes } from 'crypto'; +import { randomBytes } from 'node:crypto'; import request from 'supertest'; type UploadDto = Partial & { content?: Buffer; filename?: string }; @@ -34,9 +34,7 @@ export const assetApi = { return body as AssetResponseDto; }, get: async (server: any, accessToken: string, id: string): Promise => { - const { body, status } = await request(server) - .get(`/asset/assetById/${id}`) - .set('Authorization', `Bearer ${accessToken}`); + const { body, status } = await request(server).get(`/asset/${id}`).set('Authorization', `Bearer ${accessToken}`); expect(status).toBe(200); return body as AssetResponseDto; }, diff --git a/server/src/domain/auth/auth.dto.ts b/server/src/domain/auth/auth.dto.ts index 854ac99963..2f6f4b4b72 100644 --- a/server/src/domain/auth/auth.dto.ts +++ b/server/src/domain/auth/auth.dto.ts @@ -106,15 +106,6 @@ export class OAuthConfigDto { redirectUri!: string; } -/** @deprecated use oauth authorize */ -export class OAuthConfigResponseDto { - enabled!: boolean; - passwordLoginEnabled!: boolean; - url?: string; - buttonText?: string; - autoLaunch?: boolean; -} - export class OAuthAuthorizeResponseDto { url!: string; } diff --git a/server/src/domain/auth/auth.service.spec.ts b/server/src/domain/auth/auth.service.spec.ts index 78462cb490..8ebb75857a 100644 --- a/server/src/domain/auth/auth.service.spec.ts +++ b/server/src/domain/auth/auth.service.spec.ts @@ -429,27 +429,6 @@ describe('AuthService', () => { }); }); - describe('generateConfig', () => { - it('should work when oauth is not configured', async () => { - configMock.load.mockResolvedValue(systemConfigStub.disabled); - await expect(sut.generateConfig({ redirectUri: 'http://callback' })).resolves.toEqual({ - enabled: false, - passwordLoginEnabled: false, - }); - }); - - it('should generate the config', async () => { - configMock.load.mockResolvedValue(systemConfigStub.enabled); - await expect(sut.generateConfig({ redirectUri: 'http://redirect' })).resolves.toEqual({ - enabled: true, - buttonText: 'OAuth', - url: 'http://authorization-url', - autoLaunch: false, - passwordLoginEnabled: true, - }); - }); - }); - describe('callback', () => { it('should throw an error if OAuth is not enabled', async () => { await expect(sut.callback({ url: '' }, loginDetails)).rejects.toBeInstanceOf(BadRequestException); diff --git a/server/src/domain/auth/auth.service.ts b/server/src/domain/auth/auth.service.ts index 2acade6365..d4c2e4e189 100644 --- a/server/src/domain/auth/auth.service.ts +++ b/server/src/domain/auth/auth.service.ts @@ -42,7 +42,6 @@ import { OAuthAuthorizeResponseDto, OAuthCallbackDto, OAuthConfigDto, - OAuthConfigResponseDto, SignUpDto, mapLoginResponse, mapUserToken, @@ -201,28 +200,6 @@ export class AuthService { return `${MOBILE_REDIRECT}?${url.split('?')[1] || ''}`; } - async generateConfig(dto: OAuthConfigDto): Promise { - const config = await this.configCore.getConfig(); - const response = { - enabled: config.oauth.enabled, - passwordLoginEnabled: config.passwordLogin.enabled, - }; - - if (!response.enabled) { - return response; - } - - const { scope, buttonText, autoLaunch } = config.oauth; - const oauthClient = await this.getOAuthClient(config); - const url = oauthClient.authorizationUrl({ - redirect_uri: this.normalize(config, dto.redirectUri), - scope, - state: generators.state(), - }); - - return { ...response, buttonText, url, autoLaunch }; - } - async authorize(dto: OAuthConfigDto): Promise { const config = await this.configCore.getConfig(); if (!config.oauth.enabled) { diff --git a/server/src/domain/system-config/system-config.core.ts b/server/src/domain/system-config/system-config.core.ts index 0516e04043..1591e87d63 100644 --- a/server/src/domain/system-config/system-config.core.ts +++ b/server/src/domain/system-config/system-config.core.ts @@ -230,8 +230,6 @@ export class SystemConfigCore { [FeatureFlag.SIDECAR]: true, [FeatureFlag.SEARCH]: true, [FeatureFlag.TRASH]: config.trash.enabled, - - // TODO: use these instead of `POST oauth/config` [FeatureFlag.OAUTH]: config.oauth.enabled, [FeatureFlag.OAUTH_AUTO_LAUNCH]: config.oauth.autoLaunch, [FeatureFlag.PASSWORD_LOGIN]: config.passwordLogin.enabled, diff --git a/server/src/immich/api-v1/asset/asset.controller.ts b/server/src/immich/api-v1/asset/asset.controller.ts index ddcb8417c8..bc59e2dfef 100644 --- a/server/src/immich/api-v1/asset/asset.controller.ts +++ b/server/src/immich/api-v1/asset/asset.controller.ts @@ -1,4 +1,4 @@ -import { AssetResponseDto, AssetService, AuthDto } from '@app/domain'; +import { AssetResponseDto, AuthDto } from '@app/domain'; import { Body, Controller, @@ -18,7 +18,7 @@ import { import { ApiBody, ApiConsumes, ApiHeader, ApiTags } from '@nestjs/swagger'; import { NextFunction, Response } from 'express'; import { Auth, Authenticated, FileResponse, SharedLinkRoute } from '../../app.guard'; -import { UseValidation, sendFile } from '../../app.utils'; +import { sendFile } from '../../app.utils'; import { UUIDParamDto } from '../../controllers/dto/uuid-param.dto'; import { FileUploadInterceptor, ImmichFile, Route, mapToUploadFile } from '../../interceptors'; import FileNotEmptyValidator from '../validation/file-not-empty-validator'; @@ -45,10 +45,7 @@ interface UploadFiles { @Controller(Route.ASSET) @Authenticated() export class AssetController { - constructor( - private serviceV1: AssetServiceV1, - private service: AssetService, - ) {} + constructor(private serviceV1: AssetServiceV1) {} @SharedLinkRoute() @Post('upload') @@ -143,17 +140,6 @@ export class AssetController { return this.serviceV1.getAllAssets(auth, dto); } - /** - * Get a single asset's information - * @deprecated Use `/asset/:id` - */ - @SharedLinkRoute() - @UseValidation() - @Get('/assetById/:id') - getAssetById(@Auth() auth: AuthDto, @Param() { id }: UUIDParamDto): Promise { - return this.service.get(auth, id) as Promise; - } - /** * Checks if multiple assets exist on the server and returns all existing - used by background backup */ diff --git a/server/src/immich/controllers/asset.controller.ts b/server/src/immich/controllers/asset.controller.ts index 86a2b155ab..ad29ff080d 100644 --- a/server/src/immich/controllers/asset.controller.ts +++ b/server/src/immich/controllers/asset.controller.ts @@ -1,7 +1,6 @@ import { AssetBulkDeleteDto, AssetBulkUpdateDto, - AssetIdsDto, AssetJobsDto, AssetResponseDto, AssetSearchDto, @@ -9,10 +8,7 @@ import { AssetStatsDto, AssetStatsResponseDto, AuthDto, - BulkIdsDto, DeviceIdDto, - DownloadInfoDto, - DownloadResponseDto, DownloadService, MapMarkerDto, MapMarkerResponseDto, @@ -26,25 +22,10 @@ import { UpdateAssetDto as UpdateDto, UpdateStackParentDto, } from '@app/domain'; -import { - Body, - Controller, - Delete, - Get, - HttpCode, - HttpStatus, - Next, - Param, - Post, - Put, - Query, - Res, - StreamableFile, -} from '@nestjs/common'; +import { Body, Controller, Delete, Get, HttpCode, HttpStatus, Param, Post, Put, Query } from '@nestjs/common'; import { ApiTags } from '@nestjs/swagger'; -import { NextFunction, Response } from 'express'; -import { Auth, Authenticated, FileResponse, SharedLinkRoute } from '../app.guard'; -import { UseValidation, asStreamableFile, sendFile } from '../app.utils'; +import { Auth, Authenticated, SharedLinkRoute } from '../app.guard'; +import { UseValidation } from '../app.utils'; import { Route } from '../interceptors'; import { UUIDParamDto } from './dto/uuid-param.dto'; @@ -87,42 +68,6 @@ export class AssetController { return this.service.getRandom(auth, dto.count ?? 1); } - /** - * @deprecated use `/download/info` - */ - @SharedLinkRoute() - @Post('download/info') - getDownloadInfoOld(@Auth() auth: AuthDto, @Body() dto: DownloadInfoDto): Promise { - return this.downloadService.getDownloadInfo(auth, dto); - } - - /** - * @deprecated use `/download/archive` - */ - @SharedLinkRoute() - @Post('download/archive') - @HttpCode(HttpStatus.OK) - @FileResponse() - downloadArchiveOld(@Auth() auth: AuthDto, @Body() dto: AssetIdsDto): Promise { - return this.downloadService.downloadArchive(auth, dto).then(asStreamableFile); - } - - /** - * @deprecated use `/download/:id` - */ - @SharedLinkRoute() - @Post('download/:id') - @HttpCode(HttpStatus.OK) - @FileResponse() - async downloadFileOld( - @Res() res: Response, - @Next() next: NextFunction, - @Auth() auth: AuthDto, - @Param() { id }: UUIDParamDto, - ) { - await sendFile(res, next, () => this.downloadService.downloadFile(auth, id)); - } - /** * Get all asset of a device that are in the database, ID only. */ @@ -166,33 +111,6 @@ export class AssetController { return this.service.deleteAll(auth, dto); } - /** - * @deprecated use `POST /trash/restore/assets` - */ - @Post('restore') - @HttpCode(HttpStatus.NO_CONTENT) - restoreAssetsOld(@Auth() auth: AuthDto, @Body() dto: BulkIdsDto): Promise { - return this.trashService.restoreAssets(auth, dto); - } - - /** - * @deprecated use `POST /trash/empty` - */ - @Post('trash/empty') - @HttpCode(HttpStatus.NO_CONTENT) - emptyTrashOld(@Auth() auth: AuthDto): Promise { - return this.trashService.empty(auth); - } - - /** - * @deprecated use `POST /trash/restore` - */ - @Post('trash/restore') - @HttpCode(HttpStatus.NO_CONTENT) - restoreTrashOld(@Auth() auth: AuthDto): Promise { - return this.trashService.restore(auth); - } - @Put('stack/parent') @HttpCode(HttpStatus.OK) updateStackParent(@Auth() auth: AuthDto, @Body() dto: UpdateStackParentDto): Promise { diff --git a/server/src/immich/controllers/oauth.controller.ts b/server/src/immich/controllers/oauth.controller.ts index 678e4a4f3c..a62458715b 100644 --- a/server/src/immich/controllers/oauth.controller.ts +++ b/server/src/immich/controllers/oauth.controller.ts @@ -6,7 +6,6 @@ import { OAuthAuthorizeResponseDto, OAuthCallbackDto, OAuthConfigDto, - OAuthConfigResponseDto, UserResponseDto, } from '@app/domain'; import { Body, Controller, Get, HttpStatus, Post, Redirect, Req, Res } from '@nestjs/common'; @@ -32,13 +31,6 @@ export class OAuthController { }; } - /** @deprecated use feature flags and /oauth/authorize */ - @PublicRoute() - @Post('config') - generateOAuthConfig(@Body() dto: OAuthConfigDto): Promise { - return this.service.generateConfig(dto); - } - @PublicRoute() @Post('authorize') startOAuth(@Body() dto: OAuthConfigDto): Promise { From b67fddf4b88389e3cb4266a1bf60e1f185c96c13 Mon Sep 17 00:00:00 2001 From: Jonathan Jogenfors Date: Fri, 9 Feb 2024 01:09:09 +0100 Subject: [PATCH 049/104] fix(web): Handle duplicate library settings gracefully (#6950) * don't add duplicate import paths * improve library import paths form * same for exclusion patterns * remove newline --- .../library-exclusion-pattern-form.svelte | 22 ++++++++++-- .../forms/library-import-path-form.svelte | 27 ++++++++++++--- .../forms/library-import-paths-form.svelte | 34 ++++++++++++++----- .../forms/library-scan-settings-form.svelte | 19 +++++++---- 4 files changed, 78 insertions(+), 24 deletions(-) diff --git a/web/src/lib/components/forms/library-exclusion-pattern-form.svelte b/web/src/lib/components/forms/library-exclusion-pattern-form.svelte index fccf3b57b9..439ae2b368 100644 --- a/web/src/lib/components/forms/library-exclusion-pattern-form.svelte +++ b/web/src/lib/components/forms/library-exclusion-pattern-form.svelte @@ -4,11 +4,22 @@ import FullScreenModal from '../shared-components/full-screen-modal.svelte'; import Icon from '$lib/components/elements/icon.svelte'; import { mdiFolderRemove } from '@mdi/js'; + import { onMount } from 'svelte'; export let exclusionPattern: string; - export let canDelete = false; + export let exclusionPatterns: string[] = []; + export let isEditing = false; export let submitText = 'Submit'; + onMount(() => { + if (isEditing) { + exclusionPatterns = exclusionPatterns.filter((pattern) => pattern !== exclusionPattern); + } + }); + + $: isDuplicate = exclusionPattern !== null && exclusionPatterns.includes(exclusionPattern); + $: canSubmit = exclusionPattern !== '' && exclusionPattern !== null && !exclusionPatterns.includes(exclusionPattern); + const dispatch = createEventDispatcher<{ cancel: void; submit: { excludePattern: string }; @@ -49,11 +60,16 @@
- {#if canDelete} + {#if isEditing} {/if} - + +
+
+ {#if isDuplicate} +

This exclusion pattern already exists.

+ {/if}
diff --git a/web/src/lib/components/forms/library-import-path-form.svelte b/web/src/lib/components/forms/library-import-path-form.svelte index f01b902dce..06a5f63ea5 100644 --- a/web/src/lib/components/forms/library-import-path-form.svelte +++ b/web/src/lib/components/forms/library-import-path-form.svelte @@ -4,16 +4,27 @@ import Button from '../elements/buttons/button.svelte'; import FullScreenModal from '../shared-components/full-screen-modal.svelte'; import { mdiFolderSync } from '@mdi/js'; + import { onMount } from 'svelte'; - export let importPath: string; + export let importPath: string | null; + export let importPaths: string[] = []; export let title = 'Import path'; export let cancelText = 'Cancel'; export let submitText = 'Save'; - export let canDelete = false; + export let isEditing = false; + + onMount(() => { + if (isEditing) { + importPaths = importPaths.filter((path) => path !== importPath); + } + }); + + $: isDuplicate = importPath !== null && importPaths.includes(importPath); + $: canSubmit = importPath !== '' && importPath !== null && !importPaths.includes(importPath); const dispatch = createEventDispatcher<{ cancel: void; - submit: { importPath: string }; + submit: { importPath: string | null }; delete: void; }>(); const handleCancel = () => dispatch('cancel'); @@ -47,11 +58,17 @@
- {#if canDelete} + {#if isEditing} {/if} - + +
+ +
+ {#if isDuplicate} +

This import path already exists.

+ {/if}
diff --git a/web/src/lib/components/forms/library-import-paths-form.svelte b/web/src/lib/components/forms/library-import-paths-form.svelte index 8659cdcd05..bd32b39b5e 100644 --- a/web/src/lib/components/forms/library-import-paths-form.svelte +++ b/web/src/lib/components/forms/library-import-paths-form.svelte @@ -13,7 +13,7 @@ let addImportPath = false; let editImportPath: number | null = null; - let importPathToAdd: string; + let importPathToAdd: string | null = null; let editedImportPath: string; let importPaths: string[] = []; @@ -39,7 +39,7 @@ }; const handleAddImportPath = async () => { - if (!addImportPath) { + if (!addImportPath || !importPathToAdd) { return; } @@ -48,12 +48,16 @@ } try { - library.importPaths.push(importPathToAdd); - importPaths = library.importPaths; + // Check so that import path isn't duplicated + if (!library.importPaths.includes(importPathToAdd)) { + library.importPaths.push(importPathToAdd); + importPaths = library.importPaths; + } } catch (error) { - handleError(error, 'Unable to remove import path'); + handleError(error, 'Unable to add import path'); } finally { addImportPath = false; + importPathToAdd = null; } }; @@ -67,8 +71,13 @@ } try { - library.importPaths[editImportPath] = editedImportPath; - importPaths = library.importPaths; + // Check so that import path isn't duplicated + + if (!library.importPaths.includes(editedImportPath)) { + // Update import path + library.importPaths[editImportPath] = editedImportPath; + importPaths = library.importPaths; + } } catch (error) { editImportPath = null; handleError(error, 'Unable to edit import path'); @@ -103,9 +112,11 @@ title="Add Import Path" submitText="Add" bind:importPath={importPathToAdd} + {importPaths} on:submit={handleAddImportPath} on:cancel={() => { addImportPath = false; + importPathToAdd = null; }} /> {/if} @@ -114,8 +125,9 @@ { @@ -157,7 +169,11 @@ : 'bg-immich-bg dark:bg-immich-dark-gray/50' }`} > - + + {#if importPaths.length === 0} + No paths added + {/if}