From 77f9e87bd340bd2ea5e21ece0cd884167a6be5a0 Mon Sep 17 00:00:00 2001 From: izzy Date: Wed, 15 Apr 2026 15:17:19 +0100 Subject: [PATCH] feat: yucca integration --- .devcontainer/devcontainer.json | 5 +- .github/workflows/test.yml | 26 + e2e/package.json | 1 + .../server/yucca-backups.e2e-spec.ts | 385 ++++ .../web/database-backups.e2e-spec.ts | 1 + e2e/src/utils.ts | 7 + mobile/openapi/README.md | 83 + mobile/openapi/lib/api.dart | 59 + mobile/openapi/lib/api/auth_api.dart | 92 + mobile/openapi/lib/api/backend_api.dart | 106 + mobile/openapi/lib/api/development_api.dart | 51 + mobile/openapi/lib/api/filesystem_api.dart | 69 + mobile/openapi/lib/api/integrations_api.dart | 98 + mobile/openapi/lib/api/onboarding_api.dart | 205 ++ mobile/openapi/lib/api/repository_api.dart | 701 +++++++ mobile/openapi/lib/api/run_history_api.dart | 58 + mobile/openapi/lib/api/running_tasks_api.dart | 59 + mobile/openapi/lib/api/schedule_api.dart | 288 +++ mobile/openapi/lib/api_client.dart | 98 + mobile/openapi/lib/api_helper.dart | 12 + .../lib/model/active_schedule_item_dto.dart | 107 + mobile/openapi/lib/model/backend_dto.dart | 132 ++ .../lib/model/backend_response_dto.dart | 99 + mobile/openapi/lib/model/backend_type.dart | 88 + .../lib/model/backends_response_dto.dart | 99 + ...figure_immich_integration_request_dto.dart | 141 ++ ...ich_integration_request_dto_libraries.dart | 91 + .../create_local_backend_request_dto.dart | 99 + .../model/current_recovery_key_response.dart | 99 + .../model/filesystem_listing_item_dto.dart | 107 + .../filesystem_listing_response_dto.dart | 115 ++ .../immich_integration_configuration_dto.dart | 117 ++ .../lib/model/immich_integration_dto.dart | 115 ++ .../openapi/lib/model/immich_library_dto.dart | 127 ++ .../openapi/lib/model/immich_state_dto.dart | 117 ++ .../model/import_recovery_key_request.dart | 99 + .../model/inspected_local_repository_dto.dart | 165 ++ .../lib/model/integrations_response_dto.dart | 125 ++ .../model/list_snapshots_response_dto.dart | 99 + .../lib/model/local_repository_dto.dart | 157 ++ .../openapi/lib/model/log_response_dto.dart | 99 + .../model/onboarding_status_response_dto.dart | 131 ++ .../lib/model/repository_backend_dto.dart | 115 ++ .../lib/model/repository_backends_dto.dart | 107 + .../repository_check_import_response_dto.dart | 99 + .../model/repository_configuration_dto.dart | 101 + .../model/repository_create_request_dto.dart | 116 ++ .../model/repository_create_response_dto.dart | 99 + .../repository_inspect_response_dto.dart | 99 + .../model/repository_list_response_dto.dart | 99 + .../lib/model/repository_metrics_dto.dart | 150 ++ ...apshot_restore_from_point_request_dto.dart | 117 ++ ...pository_snapshot_restore_request_dto.dart | 117 ++ .../model/repository_update_request_dto.dart | 117 ++ .../model/repository_update_response_dto.dart | 99 + mobile/openapi/lib/model/run_dto.dart | 131 ++ .../lib/model/run_history_response_dto.dart | 99 + mobile/openapi/lib/model/run_status.dart | 88 + .../openapi/lib/model/running_task_dto.dart | 131 ++ .../lib/model/running_task_list_response.dart | 99 + .../model/schedule_create_request_dto.dart | 117 ++ .../model/schedule_create_response_dto.dart | 99 + mobile/openapi/lib/model/schedule_dto.dart | 167 ++ .../lib/model/schedule_list_response_dto.dart | 99 + .../model/schedule_update_request_dto.dart | 151 ++ .../model/schedule_update_response_dto.dart | 99 + mobile/openapi/lib/model/snapshot_dto.dart | 117 ++ mobile/openapi/lib/model/task_status.dart | 88 + mobile/openapi/lib/model/task_type.dart | 91 + open-api/immich-openapi-specs.json | 1837 +++++++++++++++++ open-api/typescript-sdk/src/fetch-client.ts | 563 +++++ pnpm-lock.yaml | 502 ++++- pnpm-workspace.yaml | 46 +- server/Dockerfile | 5 +- server/Dockerfile.dev | 2 +- server/package.json | 1 + server/src/app.module.ts | 36 +- server/src/enum.ts | 1 + server/src/main.ts | 2 +- .../src/maintenance/maintenance-auth.guard.ts | 6 +- .../maintenance-worker.service.spec.ts | 5 + .../maintenance/maintenance-worker.service.ts | 10 + server/src/middleware/yucca-admin.guard.ts | 23 + server/src/repositories/event.repository.ts | 7 + .../src/repositories/websocket.repository.ts | 2 +- server/src/services/index.ts | 2 + server/src/services/library.service.ts | 5 + server/src/services/yucca.service.ts | 113 + web/package.json | 1 + .../maintenance/MaintenanceRestoreFlow.svelte | 23 +- .../RestoreFlowDetectInstall.svelte | 6 +- .../restore-flow/RestoreFlowIntro.svelte | 20 + .../side-bar/user-sidebar.svelte | 3 + web/src/lib/route.ts | 6 + web/src/routes/backups/+layout.svelte | 44 + web/src/routes/backups/+layout.ts | 6 + web/src/routes/backups/+page.svelte | 13 + web/src/routes/backups/+page.ts | 9 + web/src/routes/backups/config/+page.svelte | 5 + .../routes/backups/repositories/+page.svelte | 5 + web/src/routes/backups/schedules/+page.svelte | 5 + web/src/routes/maintenance/+page.svelte | 105 +- 102 files changed, 11198 insertions(+), 164 deletions(-) create mode 100644 e2e/src/specs/maintenance/server/yucca-backups.e2e-spec.ts create mode 100644 mobile/openapi/lib/api/auth_api.dart create mode 100644 mobile/openapi/lib/api/backend_api.dart create mode 100644 mobile/openapi/lib/api/development_api.dart create mode 100644 mobile/openapi/lib/api/filesystem_api.dart create mode 100644 mobile/openapi/lib/api/integrations_api.dart create mode 100644 mobile/openapi/lib/api/onboarding_api.dart create mode 100644 mobile/openapi/lib/api/repository_api.dart create mode 100644 mobile/openapi/lib/api/run_history_api.dart create mode 100644 mobile/openapi/lib/api/running_tasks_api.dart create mode 100644 mobile/openapi/lib/api/schedule_api.dart create mode 100644 mobile/openapi/lib/model/active_schedule_item_dto.dart create mode 100644 mobile/openapi/lib/model/backend_dto.dart create mode 100644 mobile/openapi/lib/model/backend_response_dto.dart create mode 100644 mobile/openapi/lib/model/backend_type.dart create mode 100644 mobile/openapi/lib/model/backends_response_dto.dart create mode 100644 mobile/openapi/lib/model/configure_immich_integration_request_dto.dart create mode 100644 mobile/openapi/lib/model/configure_immich_integration_request_dto_libraries.dart create mode 100644 mobile/openapi/lib/model/create_local_backend_request_dto.dart create mode 100644 mobile/openapi/lib/model/current_recovery_key_response.dart create mode 100644 mobile/openapi/lib/model/filesystem_listing_item_dto.dart create mode 100644 mobile/openapi/lib/model/filesystem_listing_response_dto.dart create mode 100644 mobile/openapi/lib/model/immich_integration_configuration_dto.dart create mode 100644 mobile/openapi/lib/model/immich_integration_dto.dart create mode 100644 mobile/openapi/lib/model/immich_library_dto.dart create mode 100644 mobile/openapi/lib/model/immich_state_dto.dart create mode 100644 mobile/openapi/lib/model/import_recovery_key_request.dart create mode 100644 mobile/openapi/lib/model/inspected_local_repository_dto.dart create mode 100644 mobile/openapi/lib/model/integrations_response_dto.dart create mode 100644 mobile/openapi/lib/model/list_snapshots_response_dto.dart create mode 100644 mobile/openapi/lib/model/local_repository_dto.dart create mode 100644 mobile/openapi/lib/model/log_response_dto.dart create mode 100644 mobile/openapi/lib/model/onboarding_status_response_dto.dart create mode 100644 mobile/openapi/lib/model/repository_backend_dto.dart create mode 100644 mobile/openapi/lib/model/repository_backends_dto.dart create mode 100644 mobile/openapi/lib/model/repository_check_import_response_dto.dart create mode 100644 mobile/openapi/lib/model/repository_configuration_dto.dart create mode 100644 mobile/openapi/lib/model/repository_create_request_dto.dart create mode 100644 mobile/openapi/lib/model/repository_create_response_dto.dart create mode 100644 mobile/openapi/lib/model/repository_inspect_response_dto.dart create mode 100644 mobile/openapi/lib/model/repository_list_response_dto.dart create mode 100644 mobile/openapi/lib/model/repository_metrics_dto.dart create mode 100644 mobile/openapi/lib/model/repository_snapshot_restore_from_point_request_dto.dart create mode 100644 mobile/openapi/lib/model/repository_snapshot_restore_request_dto.dart create mode 100644 mobile/openapi/lib/model/repository_update_request_dto.dart create mode 100644 mobile/openapi/lib/model/repository_update_response_dto.dart create mode 100644 mobile/openapi/lib/model/run_dto.dart create mode 100644 mobile/openapi/lib/model/run_history_response_dto.dart create mode 100644 mobile/openapi/lib/model/run_status.dart create mode 100644 mobile/openapi/lib/model/running_task_dto.dart create mode 100644 mobile/openapi/lib/model/running_task_list_response.dart create mode 100644 mobile/openapi/lib/model/schedule_create_request_dto.dart create mode 100644 mobile/openapi/lib/model/schedule_create_response_dto.dart create mode 100644 mobile/openapi/lib/model/schedule_dto.dart create mode 100644 mobile/openapi/lib/model/schedule_list_response_dto.dart create mode 100644 mobile/openapi/lib/model/schedule_update_request_dto.dart create mode 100644 mobile/openapi/lib/model/schedule_update_response_dto.dart create mode 100644 mobile/openapi/lib/model/snapshot_dto.dart create mode 100644 mobile/openapi/lib/model/task_status.dart create mode 100644 mobile/openapi/lib/model/task_type.dart create mode 100644 server/src/middleware/yucca-admin.guard.ts create mode 100644 server/src/services/yucca.service.ts create mode 100644 web/src/lib/components/maintenance/restore-flow/RestoreFlowIntro.svelte create mode 100644 web/src/routes/backups/+layout.svelte create mode 100644 web/src/routes/backups/+layout.ts create mode 100644 web/src/routes/backups/+page.svelte create mode 100644 web/src/routes/backups/+page.ts create mode 100644 web/src/routes/backups/config/+page.svelte create mode 100644 web/src/routes/backups/repositories/+page.svelte create mode 100644 web/src/routes/backups/schedules/+page.svelte diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json index 1d1a6eec16..39caa1611f 100644 --- a/.devcontainer/devcontainer.json +++ b/.devcontainer/devcontainer.json @@ -85,7 +85,10 @@ "features": { "ghcr.io/devcontainers/features/docker-in-docker:2": { // https://github.com/devcontainers/features/issues/1466 - "moby": false + "moby": false, + "dockerDashComposeVersion": "none", + "installDockerBuildx": false, + "installDockerComposeSwitch": false } }, "forwardPorts": [3000, 9231, 9230, 2283], diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index a606aba124..5961d2f2c3 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -82,6 +82,8 @@ jobs: node-version-file: './server/.nvmrc' cache: 'pnpm' cache-dependency-path: '**/pnpm-lock.yaml' + - name: Configure npm registry + run: pnpm set registry https://npm.raccoon.sh/ - name: Run package manager install run: pnpm install - name: Run linter @@ -126,6 +128,8 @@ jobs: node-version-file: './cli/.nvmrc' cache: 'pnpm' cache-dependency-path: '**/pnpm-lock.yaml' + - name: Configure npm registry + run: pnpm set registry https://npm.raccoon.sh/ - name: Setup typescript-sdk run: pnpm install && pnpm run build working-directory: ./open-api/typescript-sdk @@ -173,6 +177,8 @@ jobs: node-version-file: './cli/.nvmrc' cache: 'pnpm' cache-dependency-path: '**/pnpm-lock.yaml' + - name: Configure npm registry + run: pnpm set registry https://npm.raccoon.sh/ - name: Setup typescript-sdk run: pnpm install --frozen-lockfile && pnpm build working-directory: ./open-api/typescript-sdk @@ -215,6 +221,8 @@ jobs: node-version-file: './web/.nvmrc' cache: 'pnpm' cache-dependency-path: '**/pnpm-lock.yaml' + - name: Configure npm registry + run: pnpm set registry https://npm.raccoon.sh/ - name: Run setup typescript-sdk run: pnpm install --frozen-lockfile && pnpm build working-directory: ./open-api/typescript-sdk @@ -259,6 +267,8 @@ jobs: node-version-file: './web/.nvmrc' cache: 'pnpm' cache-dependency-path: '**/pnpm-lock.yaml' + - name: Configure npm registry + run: pnpm set registry https://npm.raccoon.sh/ - name: Run setup typescript-sdk run: pnpm install --frozen-lockfile && pnpm build working-directory: ./open-api/typescript-sdk @@ -297,6 +307,8 @@ jobs: node-version-file: './web/.nvmrc' cache: 'pnpm' cache-dependency-path: '**/pnpm-lock.yaml' + - name: Configure npm registry + run: pnpm set registry https://npm.raccoon.sh/ - name: Install dependencies run: pnpm --filter=immich-i18n install --frozen-lockfile - name: Format @@ -345,6 +357,8 @@ jobs: node-version-file: './e2e/.nvmrc' cache: 'pnpm' cache-dependency-path: '**/pnpm-lock.yaml' + - name: Configure npm registry + run: pnpm set registry https://npm.raccoon.sh/ - name: Run setup typescript-sdk run: pnpm install --frozen-lockfile && pnpm build working-directory: ./open-api/typescript-sdk @@ -392,6 +406,8 @@ jobs: node-version-file: './server/.nvmrc' cache: 'pnpm' cache-dependency-path: '**/pnpm-lock.yaml' + - name: Configure npm registry + run: pnpm set registry https://npm.raccoon.sh/ - name: Run pnpm install run: SHARP_IGNORE_GLOBAL_LIBVIPS=true pnpm install --frozen-lockfile - name: Run medium tests @@ -431,6 +447,8 @@ jobs: node-version-file: './e2e/.nvmrc' cache: 'pnpm' cache-dependency-path: '**/pnpm-lock.yaml' + - name: Configure npm registry + run: pnpm set registry https://npm.raccoon.sh/ - name: Run setup typescript-sdk run: pnpm install --frozen-lockfile && pnpm build working-directory: ./open-api/typescript-sdk @@ -503,6 +521,8 @@ jobs: node-version-file: './e2e/.nvmrc' cache: 'pnpm' cache-dependency-path: '**/pnpm-lock.yaml' + - name: Configure npm registry + run: pnpm set registry https://npm.raccoon.sh/ - name: Run setup typescript-sdk run: pnpm install --frozen-lockfile && pnpm build working-directory: ./open-api/typescript-sdk @@ -668,6 +688,8 @@ jobs: node-version-file: './.github/.nvmrc' cache: 'pnpm' cache-dependency-path: '**/pnpm-lock.yaml' + - name: Configure npm registry + run: pnpm set registry https://npm.raccoon.sh/ - name: Run pnpm install run: pnpm install --frozen-lockfile - name: Run formatter @@ -719,6 +741,8 @@ jobs: node-version-file: './server/.nvmrc' cache: 'pnpm' cache-dependency-path: '**/pnpm-lock.yaml' + - name: Configure npm registry + run: pnpm set registry https://npm.raccoon.sh/ - name: Install server dependencies run: SHARP_IGNORE_GLOBAL_LIBVIPS=true pnpm --filter immich install --frozen-lockfile - name: Build the app @@ -781,6 +805,8 @@ jobs: node-version-file: './server/.nvmrc' cache: 'pnpm' cache-dependency-path: '**/pnpm-lock.yaml' + - name: Configure npm registry + run: pnpm set registry https://npm.raccoon.sh/ - name: Install server dependencies run: SHARP_IGNORE_GLOBAL_LIBVIPS=true pnpm install --frozen-lockfile - name: Build the app diff --git a/e2e/package.json b/e2e/package.json index 24b9d849ee..292566726b 100644 --- a/e2e/package.json +++ b/e2e/package.json @@ -44,6 +44,7 @@ "exiftool-vendored": "^35.0.0", "globals": "^17.0.0", "luxon": "^3.4.4", + "orchestration-ui": "0.1.54", "pg": "^8.11.3", "pngjs": "^7.0.0", "prettier": "^3.7.4", diff --git a/e2e/src/specs/maintenance/server/yucca-backups.e2e-spec.ts b/e2e/src/specs/maintenance/server/yucca-backups.e2e-spec.ts new file mode 100644 index 0000000000..4b484c21ce --- /dev/null +++ b/e2e/src/specs/maintenance/server/yucca-backups.e2e-spec.ts @@ -0,0 +1,385 @@ +import { LoginResponseDto, StorageFolder } from '@immich/sdk'; +import * as sdk from 'orchestration-ui/sdk'; +import { io, Socket } from 'socket.io-client'; +import { createUserDto } from 'src/fixtures'; +import { errorDto } from 'src/responses'; +import { app, asBearerAuth, baseUrl, utils } from 'src/utils'; +import request from 'supertest'; +import { afterAll, beforeAll, describe, expect, it } from 'vitest'; + +describe('/yucca', () => { + let admin: LoginResponseDto; + let nonAdmin: LoginResponseDto; + let requestOpts: any; + let filename: string; + + let socket: Socket; + let libraryId: string; + + beforeAll(async () => { + sdk.defaults.baseUrl = baseUrl; + + await utils.resetDatabase(); + admin = await utils.adminSetup(); + nonAdmin = await utils.userSetup(admin.accessToken, createUserDto.user1); + + requestOpts = { headers: asBearerAuth(admin.accessToken) }; + + await utils.resetBackups(admin.accessToken); + await sdk.resetOrchestrator(requestOpts); + + socket = io(baseUrl, { + path: '/api/yucca/socket.io', + transports: ['websocket'], + extraHeaders: asBearerAuth(admin.accessToken), + }); + + socket.onAny(console.info); + }); + + afterAll(async () => { + socket.close(); + + // "resetDatabase" does not reinit the module config, trigger an update / clean up + if (libraryId) { + await utils.deleteLibrary(admin.accessToken, libraryId); + } + }); + + const waitForMessage = (type: string) => { + return new Promise((resolve) => { + const listener = (msg: string) => { + const payload = JSON.parse(msg); + if (payload.type !== type) { + return; + } + + resolve(payload); + socket.offAny(listener); + }; + + socket.onAny(listener); + }); + }; + + describe('Orchestration Module', async () => { + it('works', async () => { + await expect(sdk.onboardingStatus(requestOpts)).resolves.toEqual( + expect.objectContaining({ + hasOnboardedKey: false, + hasBackend: false, + hasBackup: false, + hasSchedule: false, + hasSkippedExtraConfig: false, + }), + ); + }); + + it('is inaccessible without admin', async () => { + await expect(sdk.onboardingStatus({ headers: asBearerAuth(nonAdmin.accessToken) })).rejects.toEqual( + expect.objectContaining({ data: errorDto.forbidden }), + ); + }); + + it('is inaccessible without logging in', async () => { + await expect(sdk.onboardingStatus()).rejects.toEqual(expect.objectContaining({ data: errorDto.unauthorized })); + }); + }); + + describe.sequential('Local Backup', async () => { + beforeAll(async () => { + await sdk.importRecoveryKey( + { + recoveryKey: '0'.repeat(32), + }, + requestOpts, + ); + }); + + it.sequential('configures a local backend', async () => { + await utils.mkdir('/local-backend'); + + await sdk.createLocalBackend( + { + path: '/local-backend', + }, + requestOpts, + ); + }); + + it.sequential('configures Immich backup', async () => { + const event = waitForMessage('IntegrationUpdate'); + + await sdk.configureImmichIntegration( + { + name: 'Immich', + worm: false, + cron: '0 3 * * *', + backupConfiguration: true, + dataFolders: [StorageFolder.Backups, StorageFolder.Upload], + libraries: 'all', + }, + requestOpts, + ); + + await event; + + await expect(sdk.getIntegrations(requestOpts)).resolves.toEqual( + expect.objectContaining({ + immichIntegration: expect.objectContaining({ + configuration: { + backupConfiguration: true, + dataFolders: ['backups', 'upload'], + libraries: 'all', + }, + }), + immichState: { + dataFolders: expect.arrayContaining(Object.values(StorageFolder)), + dataPath: '/data', + libraries: [], + }, + }), + ); + }); + + it.sequential('updates configuration', async () => { + await utils.mkdir('/test'); + + ({ id: libraryId } = await utils.createLibrary(admin.accessToken, { + ownerId: admin.userId, + name: 'My Library', + importPaths: ['/test'], + })); + + await expect(sdk.getIntegrations(requestOpts)).resolves.toEqual( + expect.objectContaining({ + immichIntegration: expect.any(Object), + immichState: expect.objectContaining({ + libraries: expect.arrayContaining([ + expect.objectContaining({ + name: 'My Library', + importPaths: ['/test'], + }), + ]), + }), + }), + ); + }); + + it.sequential('creates a snapshot', async () => { + const event = waitForMessage('TaskEnd'); + + const { + repositories: [{ id }], + } = await sdk.getRepositories(requestOpts); + + filename = await utils.createBackup(admin.accessToken); + + await sdk.createBackup(id, requestOpts); + await event; + + const { + snapshots: [{ id: snapshotId }], + } = await sdk.getSnapshots(id, requestOpts); + + await expect(sdk.getSnapshotListing(id, snapshotId, {}, requestOpts)).resolves.toMatchInlineSnapshot(` + { + "items": [ + { + "isDirectory": true, + "path": "/data", + }, + { + "isDirectory": true, + "path": "/test", + }, + { + "isDirectory": true, + "path": "/yucca", + }, + ], + "parent": "/", + "path": "/", + } + `); + + await expect(sdk.getSnapshotListing(id, snapshotId, { path: '/data' }, requestOpts)).resolves + .toMatchInlineSnapshot(` + { + "items": [ + { + "isDirectory": true, + "path": "/data/backups", + }, + { + "isDirectory": true, + "path": "/data/upload", + }, + ], + "parent": "/", + "path": "/data", + } + `); + + await expect(sdk.getSnapshotListing(id, snapshotId, { path: '/data/backups' }, requestOpts)).resolves.toEqual( + expect.objectContaining({ + items: [ + { + isDirectory: false, + path: '/data/backups/.immich', + }, + { + isDirectory: false, + path: expect.stringContaining('/data/backups/immich-db-backup-'), + }, + ], + parent: '/data', + path: '/data/backups', + }), + ); + }); + }); + + describe.sequential('Restore Local Backup', async () => { + let cookie: string; + + beforeAll(async () => { + await sdk.resetOrchestrator(requestOpts); + await utils.resetDatabase(); + socket.disconnect(); + await utils.disconnectDatabase(); + }); + + afterAll(async () => { + await utils.connectDatabase(); + }); + + it.sequential( + 'restores backup', + async () => { + const { status, headers } = await request(app).post('/admin/database-backups/start-restore').send(); + expect(status).toBe(201); + cookie = headers['set-cookie'][0].split(';')[0]; + + await expect + .poll( + async () => { + const { status, body } = await request(app).get('/server/config'); + expect(status).toBe(200); + return body.maintenanceMode; + }, + { + interval: 500, + timeout: 10_000, + }, + ) + .toBeTruthy(); + + const maintenanceRequestOpts = { + headers: { + cookie, + }, + }; + + await expect(sdk.getSchedules(maintenanceRequestOpts)).resolves.toEqual({ schedules: [] }); + + await sdk.importRecoveryKey( + { + recoveryKey: '0'.repeat(32), + }, + maintenanceRequestOpts, + ); + + const { + backend: { id: backendId }, + } = await sdk.createLocalBackend( + { + path: '/local-backend', + }, + maintenanceRequestOpts, + ); + + const { + repositories: [ + { + id: repositoryId, + snapshots: [{ id: snapshotId }], + }, + ], + } = await sdk.inspectRepositories(maintenanceRequestOpts); + + socket = io(baseUrl, { + path: '/api/yucca/socket.io', + transports: ['websocket'], + extraHeaders: { + cookie, + }, + }); + + const event = waitForMessage('TaskEnd'); + await sdk.restoreFromPoint( + repositoryId, + snapshotId, + backendId, + { + yuccaConfig: '/yucca', + include: ['/data'], + }, + maintenanceRequestOpts, + ); + + await event; + socket.disconnect(); + + const { status: restoreStatus } = await request(app).post('/admin/maintenance').set('Cookie', cookie).send({ + action: 'restore_database', + restoreBackupFilename: filename, + }); + + expect(restoreStatus).toBe(201); + + await expect + .poll( + async () => { + const { status, body } = await request(app).get('/server/config'); + expect(status).toBe(200); + return body.maintenanceMode; + }, + { + interval: 500, + timeout: 10_000, + }, + ) + .toBeTruthy(); + + const { status: status2, body } = await request(app).get('/admin/maintenance/status'); + expect(status2).toBe(200); + expect(body).toEqual( + expect.objectContaining({ + active: true, + action: 'restore_database', + }), + ); + + await expect + .poll( + async () => { + const { status, body } = await request(app).get('/server/config'); + expect(status).toBe(200); + return body.maintenanceMode; + }, + { + interval: 500, + timeout: 60_000, + }, + ) + .toBeFalsy(); + + await expect(sdk.getSchedules(requestOpts)).resolves.toEqual({ + schedules: expect.arrayContaining([expect.objectContaining({ id: expect.any(String) })]), + }); + }, + 60_000, + ); + }); +}); diff --git a/e2e/src/specs/maintenance/web/database-backups.e2e-spec.ts b/e2e/src/specs/maintenance/web/database-backups.e2e-spec.ts index d101215ceb..044e1f5687 100644 --- a/e2e/src/specs/maintenance/web/database-backups.e2e-spec.ts +++ b/e2e/src/specs/maintenance/web/database-backups.e2e-spec.ts @@ -95,6 +95,7 @@ test.describe('Database Backups', () => { await page.waitForURL('/maintenance**'); } + await page.getByRole('button', { name: 'Database Backup' }).click(); await page.getByRole('button', { name: 'Next' }).click(); await page.getByRole('button', { name: 'Restore', exact: true }).click(); await page.getByRole('dialog').getByRole('button', { name: 'Restore' }).click(); diff --git a/e2e/src/utils.ts b/e2e/src/utils.ts index f9dd11a1ec..304dfb8fca 100644 --- a/e2e/src/utils.ts +++ b/e2e/src/utils.ts @@ -32,6 +32,7 @@ import { createUserAdmin, deleteAssets, deleteDatabaseBackup, + deleteLibrary, getAssetInfo, getConfig, getConfigDefaults, @@ -467,6 +468,8 @@ export const utils = { updateLibrary: (accessToken: string, id: string, dto: UpdateLibraryDto) => updateLibrary({ id, updateLibraryDto: dto }, { headers: asBearerAuth(accessToken) }), + deleteLibrary: (accessToken: string, id: string) => deleteLibrary({ id }, { headers: asBearerAuth(accessToken) }), + createPartner: (accessToken: string, id: string) => createPartner({ partnerCreateDto: { sharedWithId: id } }, { headers: asBearerAuth(accessToken) }), @@ -570,6 +573,10 @@ export const utils = { return executeCommand('docker', ['exec', 'immich-e2e-server', 'mv', source, dest]).promise; }, + async mkdir(path: string) { + return executeCommand('docker', ['exec', 'immich-e2e-server', 'mkdir', '-p', path]).promise; + }, + createBackup: async (accessToken: string) => { await utils.createJob(accessToken, { name: ManualJobName.BackupDatabase, diff --git a/mobile/openapi/README.md b/mobile/openapi/README.md index 612a65ae4e..1186c15dd1 100644 --- a/mobile/openapi/README.md +++ b/mobile/openapi/README.md @@ -119,6 +119,8 @@ Class | Method | HTTP request | Description *AssetsApi* | [**updateBulkAssetMetadata**](doc//AssetsApi.md#updatebulkassetmetadata) | **PUT** /assets/metadata | Upsert asset metadata *AssetsApi* | [**uploadAsset**](doc//AssetsApi.md#uploadasset) | **POST** /assets | Upload asset *AssetsApi* | [**viewAsset**](doc//AssetsApi.md#viewasset) | **GET** /assets/{id}/thumbnail | View asset thumbnail +*AuthApi* | [**oidcAuthorize**](doc//AuthApi.md#oidcauthorize) | **GET** /yucca/auth/oidc/login | +*AuthApi* | [**oidcCallback**](doc//AuthApi.md#oidccallback) | **GET** /yucca/auth/oidc/callback | *AuthenticationApi* | [**changePassword**](doc//AuthenticationApi.md#changepassword) | **POST** /auth/change-password | Change password *AuthenticationApi* | [**changePinCode**](doc//AuthenticationApi.md#changepincode) | **PUT** /auth/pin-code | Change pin code *AuthenticationApi* | [**finishOAuth**](doc//AuthenticationApi.md#finishoauth) | **POST** /oauth/callback | Finish OAuth @@ -136,6 +138,8 @@ Class | Method | HTTP request | Description *AuthenticationApi* | [**unlockAuthSession**](doc//AuthenticationApi.md#unlockauthsession) | **POST** /auth/session/unlock | Unlock auth session *AuthenticationApi* | [**validateAccessToken**](doc//AuthenticationApi.md#validateaccesstoken) | **POST** /auth/validateToken | Validate access token *AuthenticationAdminApi* | [**unlinkAllOAuthAccountsAdmin**](doc//AuthenticationAdminApi.md#unlinkalloauthaccountsadmin) | **POST** /admin/auth/unlink-all | Unlink all OAuth accounts +*BackendApi* | [**createLocalBackend**](doc//BackendApi.md#createlocalbackend) | **POST** /yucca/backend/local | +*BackendApi* | [**getBackends**](doc//BackendApi.md#getbackends) | **GET** /yucca/backend | *DatabaseBackupsAdminApi* | [**deleteDatabaseBackup**](doc//DatabaseBackupsAdminApi.md#deletedatabasebackup) | **DELETE** /admin/database-backups | Delete database backup *DatabaseBackupsAdminApi* | [**downloadDatabaseBackup**](doc//DatabaseBackupsAdminApi.md#downloaddatabasebackup) | **GET** /admin/database-backups/{filename} | Download database backup *DatabaseBackupsAdminApi* | [**listDatabaseBackups**](doc//DatabaseBackupsAdminApi.md#listdatabasebackups) | **GET** /admin/database-backups | List database backups @@ -147,6 +151,7 @@ Class | Method | HTTP request | Description *DeprecatedApi* | [**getFullSyncForUser**](doc//DeprecatedApi.md#getfullsyncforuser) | **POST** /sync/full-sync | Get full sync for user *DeprecatedApi* | [**getQueuesLegacy**](doc//DeprecatedApi.md#getqueueslegacy) | **GET** /jobs | Retrieve queue counts and status *DeprecatedApi* | [**runQueueCommandLegacy**](doc//DeprecatedApi.md#runqueuecommandlegacy) | **PUT** /jobs/{name} | Run jobs +*DevelopmentApi* | [**resetOrchestrator**](doc//DevelopmentApi.md#resetorchestrator) | **POST** /yucca/debug/reset | *DownloadApi* | [**downloadArchive**](doc//DownloadApi.md#downloadarchive) | **POST** /download/archive | Download asset archive *DownloadApi* | [**getDownloadInfo**](doc//DownloadApi.md#getdownloadinfo) | **POST** /download/info | Retrieve download information *DuplicatesApi* | [**deleteDuplicate**](doc//DuplicatesApi.md#deleteduplicate) | **DELETE** /duplicates/{id} | Delete a duplicate @@ -157,6 +162,9 @@ Class | Method | HTTP request | Description *FacesApi* | [**deleteFace**](doc//FacesApi.md#deleteface) | **DELETE** /faces/{id} | Delete a face *FacesApi* | [**getFaces**](doc//FacesApi.md#getfaces) | **GET** /faces | Retrieve faces for asset *FacesApi* | [**reassignFacesById**](doc//FacesApi.md#reassignfacesbyid) | **PUT** /faces/{id} | Re-assign a face to another person +*FilesystemApi* | [**getFileListing**](doc//FilesystemApi.md#getfilelisting) | **GET** /yucca/fs | +*IntegrationsApi* | [**configureImmichIntegration**](doc//IntegrationsApi.md#configureimmichintegration) | **POST** /yucca/integrations/immich | +*IntegrationsApi* | [**getIntegrations**](doc//IntegrationsApi.md#getintegrations) | **GET** /yucca/integrations | *JobsApi* | [**createJob**](doc//JobsApi.md#createjob) | **POST** /jobs | Create a manual job *JobsApi* | [**getQueuesLegacy**](doc//JobsApi.md#getqueueslegacy) | **GET** /jobs | Retrieve queue counts and status *JobsApi* | [**runQueueCommandLegacy**](doc//JobsApi.md#runqueuecommandlegacy) | **PUT** /jobs/{name} | Run jobs @@ -191,6 +199,11 @@ Class | Method | HTTP request | Description *NotificationsAdminApi* | [**createNotification**](doc//NotificationsAdminApi.md#createnotification) | **POST** /admin/notifications | Create a notification *NotificationsAdminApi* | [**getNotificationTemplateAdmin**](doc//NotificationsAdminApi.md#getnotificationtemplateadmin) | **POST** /admin/notifications/templates/{name} | Render email template *NotificationsAdminApi* | [**sendTestEmailAdmin**](doc//NotificationsAdminApi.md#sendtestemailadmin) | **POST** /admin/notifications/test-email | Send test email +*OnboardingApi* | [**confirmRecoveryKey**](doc//OnboardingApi.md#confirmrecoverykey) | **POST** /yucca/onboarding/recovery-key | +*OnboardingApi* | [**currentRecoveryKey**](doc//OnboardingApi.md#currentrecoverykey) | **GET** /yucca/onboarding/recovery-key | +*OnboardingApi* | [**importRecoveryKey**](doc//OnboardingApi.md#importrecoverykey) | **PUT** /yucca/onboarding/recovery-key | +*OnboardingApi* | [**onboardingStatus**](doc//OnboardingApi.md#onboardingstatus) | **GET** /yucca/onboarding | +*OnboardingApi* | [**skipOnboardingExtraConfig**](doc//OnboardingApi.md#skiponboardingextraconfig) | **POST** /yucca/onboarding/skip | *PartnersApi* | [**createPartner**](doc//PartnersApi.md#createpartner) | **POST** /partners | Create a partner *PartnersApi* | [**createPartnerDeprecated**](doc//PartnersApi.md#createpartnerdeprecated) | **POST** /partners/{id} | Create a partner *PartnersApi* | [**getPartners**](doc//PartnersApi.md#getpartners) | **GET** /partners | Retrieve partners @@ -215,6 +228,27 @@ Class | Method | HTTP request | Description *QueuesApi* | [**getQueueJobs**](doc//QueuesApi.md#getqueuejobs) | **GET** /queues/{name}/jobs | Retrieve queue jobs *QueuesApi* | [**getQueues**](doc//QueuesApi.md#getqueues) | **GET** /queues | List all queues *QueuesApi* | [**updateQueue**](doc//QueuesApi.md#updatequeue) | **PUT** /queues/{name} | Update a queue +*RepositoryApi* | [**checkImportRepository**](doc//RepositoryApi.md#checkimportrepository) | **GET** /yucca/repository/{id}/import | +*RepositoryApi* | [**createBackup**](doc//RepositoryApi.md#createbackup) | **POST** /yucca/repository/{id} | +*RepositoryApi* | [**createRepository**](doc//RepositoryApi.md#createrepository) | **POST** /yucca/repository | +*RepositoryApi* | [**forgetSnapshot**](doc//RepositoryApi.md#forgetsnapshot) | **DELETE** /yucca/repository/{id}/snapshots/{snapshot} | +*RepositoryApi* | [**getRepositories**](doc//RepositoryApi.md#getrepositories) | **GET** /yucca/repository | +*RepositoryApi* | [**getRunHistory**](doc//RepositoryApi.md#getrunhistory) | **GET** /yucca/repository/{id}/runs | +*RepositoryApi* | [**getSnapshotListing**](doc//RepositoryApi.md#getsnapshotlisting) | **GET** /yucca/repository/{id}/snapshots/{snapshot}/listing | +*RepositoryApi* | [**getSnapshots**](doc//RepositoryApi.md#getsnapshots) | **GET** /yucca/repository/{id}/snapshots | +*RepositoryApi* | [**importRepository**](doc//RepositoryApi.md#importrepository) | **POST** /yucca/repository/{id}/import | +*RepositoryApi* | [**inspectRepositories**](doc//RepositoryApi.md#inspectrepositories) | **GET** /yucca/repository/inspect | +*RepositoryApi* | [**restoreFromPoint**](doc//RepositoryApi.md#restorefrompoint) | **POST** /yucca/repository/{id}/snapshots/{snapshot}/restore-from-point | +*RepositoryApi* | [**restoreSnapshot**](doc//RepositoryApi.md#restoresnapshot) | **POST** /yucca/repository/{id}/snapshots/{snapshot} | +*RepositoryApi* | [**updateRepository**](doc//RepositoryApi.md#updaterepository) | **PATCH** /yucca/repository/{id} | +*RunHistoryApi* | [**logStreamSse**](doc//RunHistoryApi.md#logstreamsse) | **GET** /yucca/logs/{id} | +*RunningTasksApi* | [**getRunningTasks**](doc//RunningTasksApi.md#getrunningtasks) | **GET** /yucca/tasks | +*ScheduleApi* | [**addRepositoryToSchedule**](doc//ScheduleApi.md#addrepositorytoschedule) | **PUT** /yucca/schedule/{id}/{repositoryId} | +*ScheduleApi* | [**createSchedule**](doc//ScheduleApi.md#createschedule) | **POST** /yucca/schedule | +*ScheduleApi* | [**getSchedules**](doc//ScheduleApi.md#getschedules) | **GET** /yucca/schedule | +*ScheduleApi* | [**removeRepositoryFromSchedule**](doc//ScheduleApi.md#removerepositoryfromschedule) | **DELETE** /yucca/schedule/{id}/{repositoryId} | +*ScheduleApi* | [**removeSchedule**](doc//ScheduleApi.md#removeschedule) | **DELETE** /yucca/schedule/{id} | +*ScheduleApi* | [**updateSchedule**](doc//ScheduleApi.md#updateschedule) | **PATCH** /yucca/schedule/{id} | *SearchApi* | [**getAssetsByCity**](doc//SearchApi.md#getassetsbycity) | **GET** /search/cities | Retrieve assets by city *SearchApi* | [**getExploreData**](doc//SearchApi.md#getexploredata) | **GET** /search/explore | Retrieve explore data *SearchApi* | [**getSearchSuggestions**](doc//SearchApi.md#getsearchsuggestions) | **GET** /search/suggestions | Retrieve search suggestions @@ -330,6 +364,7 @@ Class | Method | HTTP request | Description - [APIKeyCreateResponseDto](doc//APIKeyCreateResponseDto.md) - [APIKeyResponseDto](doc//APIKeyResponseDto.md) - [APIKeyUpdateDto](doc//APIKeyUpdateDto.md) + - [ActiveScheduleItemDto](doc//ActiveScheduleItemDto.md) - [ActivityCreateDto](doc//ActivityCreateDto.md) - [ActivityResponseDto](doc//ActivityResponseDto.md) - [ActivityStatisticsResponseDto](doc//ActivityStatisticsResponseDto.md) @@ -395,6 +430,10 @@ Class | Method | HTTP request | Description - [AudioCodec](doc//AudioCodec.md) - [AuthStatusResponseDto](doc//AuthStatusResponseDto.md) - [AvatarUpdate](doc//AvatarUpdate.md) + - [BackendDto](doc//BackendDto.md) + - [BackendResponseDto](doc//BackendResponseDto.md) + - [BackendType](doc//BackendType.md) + - [BackendsResponseDto](doc//BackendsResponseDto.md) - [BulkIdErrorReason](doc//BulkIdErrorReason.md) - [BulkIdResponseDto](doc//BulkIdResponseDto.md) - [BulkIdsDto](doc//BulkIdsDto.md) @@ -406,11 +445,15 @@ Class | Method | HTTP request | Description - [CheckExistingAssetsDto](doc//CheckExistingAssetsDto.md) - [CheckExistingAssetsResponseDto](doc//CheckExistingAssetsResponseDto.md) - [Colorspace](doc//Colorspace.md) + - [ConfigureImmichIntegrationRequestDto](doc//ConfigureImmichIntegrationRequestDto.md) + - [ConfigureImmichIntegrationRequestDtoLibraries](doc//ConfigureImmichIntegrationRequestDtoLibraries.md) - [ContributorCountResponseDto](doc//ContributorCountResponseDto.md) - [CreateAlbumDto](doc//CreateAlbumDto.md) - [CreateLibraryDto](doc//CreateLibraryDto.md) + - [CreateLocalBackendRequestDto](doc//CreateLocalBackendRequestDto.md) - [CreateProfileImageResponseDto](doc//CreateProfileImageResponseDto.md) - [CropParameters](doc//CropParameters.md) + - [CurrentRecoveryKeyResponse](doc//CurrentRecoveryKeyResponse.md) - [DatabaseBackupConfig](doc//DatabaseBackupConfig.md) - [DatabaseBackupDeleteDto](doc//DatabaseBackupDeleteDto.md) - [DatabaseBackupDto](doc//DatabaseBackupDto.md) @@ -430,16 +473,28 @@ Class | Method | HTTP request | Description - [ExifResponseDto](doc//ExifResponseDto.md) - [FaceDto](doc//FaceDto.md) - [FacialRecognitionConfig](doc//FacialRecognitionConfig.md) + - [FilesystemListingItemDto](doc//FilesystemListingItemDto.md) + - [FilesystemListingResponseDto](doc//FilesystemListingResponseDto.md) - [FoldersResponse](doc//FoldersResponse.md) - [FoldersUpdate](doc//FoldersUpdate.md) - [ImageFormat](doc//ImageFormat.md) + - [ImmichIntegrationConfigurationDto](doc//ImmichIntegrationConfigurationDto.md) + - [ImmichIntegrationDto](doc//ImmichIntegrationDto.md) + - [ImmichLibraryDto](doc//ImmichLibraryDto.md) + - [ImmichStateDto](doc//ImmichStateDto.md) + - [ImportRecoveryKeyRequest](doc//ImportRecoveryKeyRequest.md) + - [InspectedLocalRepositoryDto](doc//InspectedLocalRepositoryDto.md) + - [IntegrationsResponseDto](doc//IntegrationsResponseDto.md) - [JobCreateDto](doc//JobCreateDto.md) - [JobName](doc//JobName.md) - [JobSettingsDto](doc//JobSettingsDto.md) - [LibraryResponseDto](doc//LibraryResponseDto.md) - [LibraryStatsResponseDto](doc//LibraryStatsResponseDto.md) - [LicenseKeyDto](doc//LicenseKeyDto.md) + - [ListSnapshotsResponseDto](doc//ListSnapshotsResponseDto.md) + - [LocalRepositoryDto](doc//LocalRepositoryDto.md) - [LogLevel](doc//LogLevel.md) + - [LogResponseDto](doc//LogResponseDto.md) - [LoginCredentialDto](doc//LoginCredentialDto.md) - [LoginResponseDto](doc//LoginResponseDto.md) - [LogoutResponseDto](doc//LogoutResponseDto.md) @@ -480,6 +535,7 @@ Class | Method | HTTP request | Description - [OnThisDayDto](doc//OnThisDayDto.md) - [OnboardingDto](doc//OnboardingDto.md) - [OnboardingResponseDto](doc//OnboardingResponseDto.md) + - [OnboardingStatusResponseDto](doc//OnboardingStatusResponseDto.md) - [PartnerCreateDto](doc//PartnerCreateDto.md) - [PartnerDirection](doc//PartnerDirection.md) - [PartnerResponseDto](doc//PartnerResponseDto.md) @@ -528,8 +584,32 @@ Class | Method | HTTP request | Description - [RatingsUpdate](doc//RatingsUpdate.md) - [ReactionLevel](doc//ReactionLevel.md) - [ReactionType](doc//ReactionType.md) + - [RepositoryBackendDto](doc//RepositoryBackendDto.md) + - [RepositoryBackendsDto](doc//RepositoryBackendsDto.md) + - [RepositoryCheckImportResponseDto](doc//RepositoryCheckImportResponseDto.md) + - [RepositoryConfigurationDto](doc//RepositoryConfigurationDto.md) + - [RepositoryCreateRequestDto](doc//RepositoryCreateRequestDto.md) + - [RepositoryCreateResponseDto](doc//RepositoryCreateResponseDto.md) + - [RepositoryInspectResponseDto](doc//RepositoryInspectResponseDto.md) + - [RepositoryListResponseDto](doc//RepositoryListResponseDto.md) + - [RepositoryMetricsDto](doc//RepositoryMetricsDto.md) + - [RepositorySnapshotRestoreFromPointRequestDto](doc//RepositorySnapshotRestoreFromPointRequestDto.md) + - [RepositorySnapshotRestoreRequestDto](doc//RepositorySnapshotRestoreRequestDto.md) + - [RepositoryUpdateRequestDto](doc//RepositoryUpdateRequestDto.md) + - [RepositoryUpdateResponseDto](doc//RepositoryUpdateResponseDto.md) - [ReverseGeocodingStateResponseDto](doc//ReverseGeocodingStateResponseDto.md) - [RotateParameters](doc//RotateParameters.md) + - [RunDto](doc//RunDto.md) + - [RunHistoryResponseDto](doc//RunHistoryResponseDto.md) + - [RunStatus](doc//RunStatus.md) + - [RunningTaskDto](doc//RunningTaskDto.md) + - [RunningTaskListResponse](doc//RunningTaskListResponse.md) + - [ScheduleCreateRequestDto](doc//ScheduleCreateRequestDto.md) + - [ScheduleCreateResponseDto](doc//ScheduleCreateResponseDto.md) + - [ScheduleDto](doc//ScheduleDto.md) + - [ScheduleListResponseDto](doc//ScheduleListResponseDto.md) + - [ScheduleUpdateRequestDto](doc//ScheduleUpdateRequestDto.md) + - [ScheduleUpdateResponseDto](doc//ScheduleUpdateResponseDto.md) - [SearchAlbumResponseDto](doc//SearchAlbumResponseDto.md) - [SearchAssetResponseDto](doc//SearchAssetResponseDto.md) - [SearchExploreItem](doc//SearchExploreItem.md) @@ -565,6 +645,7 @@ Class | Method | HTTP request | Description - [SharedLinksUpdate](doc//SharedLinksUpdate.md) - [SignUpDto](doc//SignUpDto.md) - [SmartSearchDto](doc//SmartSearchDto.md) + - [SnapshotDto](doc//SnapshotDto.md) - [SourceType](doc//SourceType.md) - [StackCreateDto](doc//StackCreateDto.md) - [StackResponseDto](doc//StackResponseDto.md) @@ -647,6 +728,8 @@ Class | Method | HTTP request | Description - [TagUpsertDto](doc//TagUpsertDto.md) - [TagsResponse](doc//TagsResponse.md) - [TagsUpdate](doc//TagsUpdate.md) + - [TaskStatus](doc//TaskStatus.md) + - [TaskType](doc//TaskType.md) - [TemplateDto](doc//TemplateDto.md) - [TemplateResponseDto](doc//TemplateResponseDto.md) - [TestEmailResponseDto](doc//TestEmailResponseDto.md) diff --git a/mobile/openapi/lib/api.dart b/mobile/openapi/lib/api.dart index 9403852ef0..4dab946e63 100644 --- a/mobile/openapi/lib/api.dart +++ b/mobile/openapi/lib/api.dart @@ -34,13 +34,18 @@ part 'api/api_keys_api.dart'; part 'api/activities_api.dart'; part 'api/albums_api.dart'; part 'api/assets_api.dart'; +part 'api/auth_api.dart'; part 'api/authentication_api.dart'; part 'api/authentication_admin_api.dart'; +part 'api/backend_api.dart'; part 'api/database_backups_admin_api.dart'; part 'api/deprecated_api.dart'; +part 'api/development_api.dart'; part 'api/download_api.dart'; part 'api/duplicates_api.dart'; part 'api/faces_api.dart'; +part 'api/filesystem_api.dart'; +part 'api/integrations_api.dart'; part 'api/jobs_api.dart'; part 'api/libraries_api.dart'; part 'api/maintenance_admin_api.dart'; @@ -48,10 +53,15 @@ part 'api/map_api.dart'; part 'api/memories_api.dart'; part 'api/notifications_api.dart'; part 'api/notifications_admin_api.dart'; +part 'api/onboarding_api.dart'; part 'api/partners_api.dart'; part 'api/people_api.dart'; part 'api/plugins_api.dart'; part 'api/queues_api.dart'; +part 'api/repository_api.dart'; +part 'api/run_history_api.dart'; +part 'api/running_tasks_api.dart'; +part 'api/schedule_api.dart'; part 'api/search_api.dart'; part 'api/server_api.dart'; part 'api/sessions_api.dart'; @@ -72,6 +82,7 @@ part 'model/api_key_create_dto.dart'; part 'model/api_key_create_response_dto.dart'; part 'model/api_key_response_dto.dart'; part 'model/api_key_update_dto.dart'; +part 'model/active_schedule_item_dto.dart'; part 'model/activity_create_dto.dart'; part 'model/activity_response_dto.dart'; part 'model/activity_statistics_response_dto.dart'; @@ -137,6 +148,10 @@ part 'model/asset_visibility.dart'; part 'model/audio_codec.dart'; part 'model/auth_status_response_dto.dart'; part 'model/avatar_update.dart'; +part 'model/backend_dto.dart'; +part 'model/backend_response_dto.dart'; +part 'model/backend_type.dart'; +part 'model/backends_response_dto.dart'; part 'model/bulk_id_error_reason.dart'; part 'model/bulk_id_response_dto.dart'; part 'model/bulk_ids_dto.dart'; @@ -148,11 +163,15 @@ part 'model/change_password_dto.dart'; part 'model/check_existing_assets_dto.dart'; part 'model/check_existing_assets_response_dto.dart'; part 'model/colorspace.dart'; +part 'model/configure_immich_integration_request_dto.dart'; +part 'model/configure_immich_integration_request_dto_libraries.dart'; part 'model/contributor_count_response_dto.dart'; part 'model/create_album_dto.dart'; part 'model/create_library_dto.dart'; +part 'model/create_local_backend_request_dto.dart'; part 'model/create_profile_image_response_dto.dart'; part 'model/crop_parameters.dart'; +part 'model/current_recovery_key_response.dart'; part 'model/database_backup_config.dart'; part 'model/database_backup_delete_dto.dart'; part 'model/database_backup_dto.dart'; @@ -172,16 +191,28 @@ part 'model/email_notifications_update.dart'; part 'model/exif_response_dto.dart'; part 'model/face_dto.dart'; part 'model/facial_recognition_config.dart'; +part 'model/filesystem_listing_item_dto.dart'; +part 'model/filesystem_listing_response_dto.dart'; part 'model/folders_response.dart'; part 'model/folders_update.dart'; part 'model/image_format.dart'; +part 'model/immich_integration_configuration_dto.dart'; +part 'model/immich_integration_dto.dart'; +part 'model/immich_library_dto.dart'; +part 'model/immich_state_dto.dart'; +part 'model/import_recovery_key_request.dart'; +part 'model/inspected_local_repository_dto.dart'; +part 'model/integrations_response_dto.dart'; part 'model/job_create_dto.dart'; part 'model/job_name.dart'; part 'model/job_settings_dto.dart'; part 'model/library_response_dto.dart'; part 'model/library_stats_response_dto.dart'; part 'model/license_key_dto.dart'; +part 'model/list_snapshots_response_dto.dart'; +part 'model/local_repository_dto.dart'; part 'model/log_level.dart'; +part 'model/log_response_dto.dart'; part 'model/login_credential_dto.dart'; part 'model/login_response_dto.dart'; part 'model/logout_response_dto.dart'; @@ -222,6 +253,7 @@ part 'model/ocr_config.dart'; part 'model/on_this_day_dto.dart'; part 'model/onboarding_dto.dart'; part 'model/onboarding_response_dto.dart'; +part 'model/onboarding_status_response_dto.dart'; part 'model/partner_create_dto.dart'; part 'model/partner_direction.dart'; part 'model/partner_response_dto.dart'; @@ -270,8 +302,32 @@ part 'model/ratings_response.dart'; part 'model/ratings_update.dart'; part 'model/reaction_level.dart'; part 'model/reaction_type.dart'; +part 'model/repository_backend_dto.dart'; +part 'model/repository_backends_dto.dart'; +part 'model/repository_check_import_response_dto.dart'; +part 'model/repository_configuration_dto.dart'; +part 'model/repository_create_request_dto.dart'; +part 'model/repository_create_response_dto.dart'; +part 'model/repository_inspect_response_dto.dart'; +part 'model/repository_list_response_dto.dart'; +part 'model/repository_metrics_dto.dart'; +part 'model/repository_snapshot_restore_from_point_request_dto.dart'; +part 'model/repository_snapshot_restore_request_dto.dart'; +part 'model/repository_update_request_dto.dart'; +part 'model/repository_update_response_dto.dart'; part 'model/reverse_geocoding_state_response_dto.dart'; part 'model/rotate_parameters.dart'; +part 'model/run_dto.dart'; +part 'model/run_history_response_dto.dart'; +part 'model/run_status.dart'; +part 'model/running_task_dto.dart'; +part 'model/running_task_list_response.dart'; +part 'model/schedule_create_request_dto.dart'; +part 'model/schedule_create_response_dto.dart'; +part 'model/schedule_dto.dart'; +part 'model/schedule_list_response_dto.dart'; +part 'model/schedule_update_request_dto.dart'; +part 'model/schedule_update_response_dto.dart'; part 'model/search_album_response_dto.dart'; part 'model/search_asset_response_dto.dart'; part 'model/search_explore_item.dart'; @@ -307,6 +363,7 @@ part 'model/shared_links_response.dart'; part 'model/shared_links_update.dart'; part 'model/sign_up_dto.dart'; part 'model/smart_search_dto.dart'; +part 'model/snapshot_dto.dart'; part 'model/source_type.dart'; part 'model/stack_create_dto.dart'; part 'model/stack_response_dto.dart'; @@ -389,6 +446,8 @@ part 'model/tag_update_dto.dart'; part 'model/tag_upsert_dto.dart'; part 'model/tags_response.dart'; part 'model/tags_update.dart'; +part 'model/task_status.dart'; +part 'model/task_type.dart'; part 'model/template_dto.dart'; part 'model/template_response_dto.dart'; part 'model/test_email_response_dto.dart'; diff --git a/mobile/openapi/lib/api/auth_api.dart b/mobile/openapi/lib/api/auth_api.dart new file mode 100644 index 0000000000..30f39f2b21 --- /dev/null +++ b/mobile/openapi/lib/api/auth_api.dart @@ -0,0 +1,92 @@ +// +// AUTO-GENERATED FILE, DO NOT MODIFY! +// +// @dart=2.18 + +// ignore_for_file: unused_element, unused_import +// ignore_for_file: always_put_required_named_parameters_first +// ignore_for_file: constant_identifier_names +// ignore_for_file: lines_longer_than_80_chars + +part of openapi.api; + + +class AuthApi { + AuthApi([ApiClient? apiClient]) : apiClient = apiClient ?? defaultApiClient; + + final ApiClient apiClient; + + /// Performs an HTTP 'GET /yucca/auth/oidc/login' operation and returns the [Response]. + /// Parameters: + /// + /// * [String] next (required): + Future oidcAuthorizeWithHttpInfo(String next,) async { + // ignore: prefer_const_declarations + final apiPath = r'/yucca/auth/oidc/login'; + + // ignore: prefer_final_locals + Object? postBody; + + final queryParams = []; + final headerParams = {}; + final formParams = {}; + + queryParams.addAll(_queryParams('', 'next', next)); + + const contentTypes = []; + + + return apiClient.invokeAPI( + apiPath, + 'GET', + queryParams, + postBody, + headerParams, + formParams, + contentTypes.isEmpty ? null : contentTypes.first, + ); + } + + /// Parameters: + /// + /// * [String] next (required): + Future oidcAuthorize(String next,) async { + final response = await oidcAuthorizeWithHttpInfo(next,); + if (response.statusCode >= HttpStatus.badRequest) { + throw ApiException(response.statusCode, await _decodeBodyBytes(response)); + } + } + + /// Performs an HTTP 'GET /yucca/auth/oidc/callback' operation and returns the [Response]. + Future oidcCallbackWithHttpInfo() async { + // ignore: prefer_const_declarations + final apiPath = r'/yucca/auth/oidc/callback'; + + // ignore: prefer_final_locals + Object? postBody; + + final queryParams = []; + final headerParams = {}; + final formParams = {}; + + const contentTypes = []; + + + return apiClient.invokeAPI( + apiPath, + 'GET', + queryParams, + postBody, + headerParams, + formParams, + contentTypes.isEmpty ? null : contentTypes.first, + ); + } + + Future oidcCallback() async { + final response = await oidcCallbackWithHttpInfo(); + if (response.statusCode >= HttpStatus.badRequest) { + throw ApiException(response.statusCode, await _decodeBodyBytes(response)); + } + } +} diff --git a/mobile/openapi/lib/api/backend_api.dart b/mobile/openapi/lib/api/backend_api.dart new file mode 100644 index 0000000000..1b6d3138a5 --- /dev/null +++ b/mobile/openapi/lib/api/backend_api.dart @@ -0,0 +1,106 @@ +// +// AUTO-GENERATED FILE, DO NOT MODIFY! +// +// @dart=2.18 + +// ignore_for_file: unused_element, unused_import +// ignore_for_file: always_put_required_named_parameters_first +// ignore_for_file: constant_identifier_names +// ignore_for_file: lines_longer_than_80_chars + +part of openapi.api; + + +class BackendApi { + BackendApi([ApiClient? apiClient]) : apiClient = apiClient ?? defaultApiClient; + + final ApiClient apiClient; + + /// Performs an HTTP 'POST /yucca/backend/local' operation and returns the [Response]. + /// Parameters: + /// + /// * [CreateLocalBackendRequestDto] createLocalBackendRequestDto (required): + Future createLocalBackendWithHttpInfo(CreateLocalBackendRequestDto createLocalBackendRequestDto,) async { + // ignore: prefer_const_declarations + final apiPath = r'/yucca/backend/local'; + + // ignore: prefer_final_locals + Object? postBody = createLocalBackendRequestDto; + + final queryParams = []; + final headerParams = {}; + final formParams = {}; + + const contentTypes = ['application/json']; + + + return apiClient.invokeAPI( + apiPath, + 'POST', + queryParams, + postBody, + headerParams, + formParams, + contentTypes.isEmpty ? null : contentTypes.first, + ); + } + + /// Parameters: + /// + /// * [CreateLocalBackendRequestDto] createLocalBackendRequestDto (required): + Future createLocalBackend(CreateLocalBackendRequestDto createLocalBackendRequestDto,) async { + final response = await createLocalBackendWithHttpInfo(createLocalBackendRequestDto,); + 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), 'BackendResponseDto',) as BackendResponseDto; + + } + return null; + } + + /// Performs an HTTP 'GET /yucca/backend' operation and returns the [Response]. + Future getBackendsWithHttpInfo() async { + // ignore: prefer_const_declarations + final apiPath = r'/yucca/backend'; + + // ignore: prefer_final_locals + Object? postBody; + + final queryParams = []; + final headerParams = {}; + final formParams = {}; + + const contentTypes = []; + + + return apiClient.invokeAPI( + apiPath, + 'GET', + queryParams, + postBody, + headerParams, + formParams, + contentTypes.isEmpty ? null : contentTypes.first, + ); + } + + Future getBackends() async { + final response = await getBackendsWithHttpInfo(); + 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), 'BackendsResponseDto',) as BackendsResponseDto; + + } + return null; + } +} diff --git a/mobile/openapi/lib/api/development_api.dart b/mobile/openapi/lib/api/development_api.dart new file mode 100644 index 0000000000..6b62829c7f --- /dev/null +++ b/mobile/openapi/lib/api/development_api.dart @@ -0,0 +1,51 @@ +// +// AUTO-GENERATED FILE, DO NOT MODIFY! +// +// @dart=2.18 + +// ignore_for_file: unused_element, unused_import +// ignore_for_file: always_put_required_named_parameters_first +// ignore_for_file: constant_identifier_names +// ignore_for_file: lines_longer_than_80_chars + +part of openapi.api; + + +class DevelopmentApi { + DevelopmentApi([ApiClient? apiClient]) : apiClient = apiClient ?? defaultApiClient; + + final ApiClient apiClient; + + /// Performs an HTTP 'POST /yucca/debug/reset' operation and returns the [Response]. + Future resetOrchestratorWithHttpInfo() async { + // ignore: prefer_const_declarations + final apiPath = r'/yucca/debug/reset'; + + // ignore: prefer_final_locals + Object? postBody; + + final queryParams = []; + final headerParams = {}; + final formParams = {}; + + const contentTypes = []; + + + return apiClient.invokeAPI( + apiPath, + 'POST', + queryParams, + postBody, + headerParams, + formParams, + contentTypes.isEmpty ? null : contentTypes.first, + ); + } + + Future resetOrchestrator() async { + final response = await resetOrchestratorWithHttpInfo(); + if (response.statusCode >= HttpStatus.badRequest) { + throw ApiException(response.statusCode, await _decodeBodyBytes(response)); + } + } +} diff --git a/mobile/openapi/lib/api/filesystem_api.dart b/mobile/openapi/lib/api/filesystem_api.dart new file mode 100644 index 0000000000..951e745ddc --- /dev/null +++ b/mobile/openapi/lib/api/filesystem_api.dart @@ -0,0 +1,69 @@ +// +// AUTO-GENERATED FILE, DO NOT MODIFY! +// +// @dart=2.18 + +// ignore_for_file: unused_element, unused_import +// ignore_for_file: always_put_required_named_parameters_first +// ignore_for_file: constant_identifier_names +// ignore_for_file: lines_longer_than_80_chars + +part of openapi.api; + + +class FilesystemApi { + FilesystemApi([ApiClient? apiClient]) : apiClient = apiClient ?? defaultApiClient; + + final ApiClient apiClient; + + /// Performs an HTTP 'GET /yucca/fs' operation and returns the [Response]. + /// Parameters: + /// + /// * [String] path: + Future getFileListingWithHttpInfo({ String? path, }) async { + // ignore: prefer_const_declarations + final apiPath = r'/yucca/fs'; + + // ignore: prefer_final_locals + Object? postBody; + + final queryParams = []; + final headerParams = {}; + final formParams = {}; + + if (path != null) { + queryParams.addAll(_queryParams('', 'path', path)); + } + + const contentTypes = []; + + + return apiClient.invokeAPI( + apiPath, + 'GET', + queryParams, + postBody, + headerParams, + formParams, + contentTypes.isEmpty ? null : contentTypes.first, + ); + } + + /// Parameters: + /// + /// * [String] path: + Future getFileListing({ String? path, }) async { + final response = await getFileListingWithHttpInfo( path: path, ); + 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), 'FilesystemListingResponseDto',) as FilesystemListingResponseDto; + + } + return null; + } +} diff --git a/mobile/openapi/lib/api/integrations_api.dart b/mobile/openapi/lib/api/integrations_api.dart new file mode 100644 index 0000000000..67b98954c6 --- /dev/null +++ b/mobile/openapi/lib/api/integrations_api.dart @@ -0,0 +1,98 @@ +// +// AUTO-GENERATED FILE, DO NOT MODIFY! +// +// @dart=2.18 + +// ignore_for_file: unused_element, unused_import +// ignore_for_file: always_put_required_named_parameters_first +// ignore_for_file: constant_identifier_names +// ignore_for_file: lines_longer_than_80_chars + +part of openapi.api; + + +class IntegrationsApi { + IntegrationsApi([ApiClient? apiClient]) : apiClient = apiClient ?? defaultApiClient; + + final ApiClient apiClient; + + /// Performs an HTTP 'POST /yucca/integrations/immich' operation and returns the [Response]. + /// Parameters: + /// + /// * [ConfigureImmichIntegrationRequestDto] configureImmichIntegrationRequestDto (required): + Future configureImmichIntegrationWithHttpInfo(ConfigureImmichIntegrationRequestDto configureImmichIntegrationRequestDto,) async { + // ignore: prefer_const_declarations + final apiPath = r'/yucca/integrations/immich'; + + // ignore: prefer_final_locals + Object? postBody = configureImmichIntegrationRequestDto; + + final queryParams = []; + final headerParams = {}; + final formParams = {}; + + const contentTypes = ['application/json']; + + + return apiClient.invokeAPI( + apiPath, + 'POST', + queryParams, + postBody, + headerParams, + formParams, + contentTypes.isEmpty ? null : contentTypes.first, + ); + } + + /// Parameters: + /// + /// * [ConfigureImmichIntegrationRequestDto] configureImmichIntegrationRequestDto (required): + Future configureImmichIntegration(ConfigureImmichIntegrationRequestDto configureImmichIntegrationRequestDto,) async { + final response = await configureImmichIntegrationWithHttpInfo(configureImmichIntegrationRequestDto,); + if (response.statusCode >= HttpStatus.badRequest) { + throw ApiException(response.statusCode, await _decodeBodyBytes(response)); + } + } + + /// Performs an HTTP 'GET /yucca/integrations' operation and returns the [Response]. + Future getIntegrationsWithHttpInfo() async { + // ignore: prefer_const_declarations + final apiPath = r'/yucca/integrations'; + + // ignore: prefer_final_locals + Object? postBody; + + final queryParams = []; + final headerParams = {}; + final formParams = {}; + + const contentTypes = []; + + + return apiClient.invokeAPI( + apiPath, + 'GET', + queryParams, + postBody, + headerParams, + formParams, + contentTypes.isEmpty ? null : contentTypes.first, + ); + } + + Future getIntegrations() async { + final response = await getIntegrationsWithHttpInfo(); + 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), 'IntegrationsResponseDto',) as IntegrationsResponseDto; + + } + return null; + } +} diff --git a/mobile/openapi/lib/api/onboarding_api.dart b/mobile/openapi/lib/api/onboarding_api.dart new file mode 100644 index 0000000000..12f3540253 --- /dev/null +++ b/mobile/openapi/lib/api/onboarding_api.dart @@ -0,0 +1,205 @@ +// +// AUTO-GENERATED FILE, DO NOT MODIFY! +// +// @dart=2.18 + +// ignore_for_file: unused_element, unused_import +// ignore_for_file: always_put_required_named_parameters_first +// ignore_for_file: constant_identifier_names +// ignore_for_file: lines_longer_than_80_chars + +part of openapi.api; + + +class OnboardingApi { + OnboardingApi([ApiClient? apiClient]) : apiClient = apiClient ?? defaultApiClient; + + final ApiClient apiClient; + + /// Performs an HTTP 'POST /yucca/onboarding/recovery-key' operation and returns the [Response]. + Future confirmRecoveryKeyWithHttpInfo() async { + // ignore: prefer_const_declarations + final apiPath = r'/yucca/onboarding/recovery-key'; + + // ignore: prefer_final_locals + Object? postBody; + + final queryParams = []; + final headerParams = {}; + final formParams = {}; + + const contentTypes = []; + + + return apiClient.invokeAPI( + apiPath, + 'POST', + queryParams, + postBody, + headerParams, + formParams, + contentTypes.isEmpty ? null : contentTypes.first, + ); + } + + Future confirmRecoveryKey() async { + final response = await confirmRecoveryKeyWithHttpInfo(); + if (response.statusCode >= HttpStatus.badRequest) { + throw ApiException(response.statusCode, await _decodeBodyBytes(response)); + } + } + + /// Performs an HTTP 'GET /yucca/onboarding/recovery-key' operation and returns the [Response]. + Future currentRecoveryKeyWithHttpInfo() async { + // ignore: prefer_const_declarations + final apiPath = r'/yucca/onboarding/recovery-key'; + + // ignore: prefer_final_locals + Object? postBody; + + final queryParams = []; + final headerParams = {}; + final formParams = {}; + + const contentTypes = []; + + + return apiClient.invokeAPI( + apiPath, + 'GET', + queryParams, + postBody, + headerParams, + formParams, + contentTypes.isEmpty ? null : contentTypes.first, + ); + } + + Future currentRecoveryKey() async { + final response = await currentRecoveryKeyWithHttpInfo(); + 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), 'CurrentRecoveryKeyResponse',) as CurrentRecoveryKeyResponse; + + } + return null; + } + + /// Performs an HTTP 'PUT /yucca/onboarding/recovery-key' operation and returns the [Response]. + /// Parameters: + /// + /// * [ImportRecoveryKeyRequest] importRecoveryKeyRequest (required): + Future importRecoveryKeyWithHttpInfo(ImportRecoveryKeyRequest importRecoveryKeyRequest,) async { + // ignore: prefer_const_declarations + final apiPath = r'/yucca/onboarding/recovery-key'; + + // ignore: prefer_final_locals + Object? postBody = importRecoveryKeyRequest; + + final queryParams = []; + final headerParams = {}; + final formParams = {}; + + const contentTypes = ['application/json']; + + + return apiClient.invokeAPI( + apiPath, + 'PUT', + queryParams, + postBody, + headerParams, + formParams, + contentTypes.isEmpty ? null : contentTypes.first, + ); + } + + /// Parameters: + /// + /// * [ImportRecoveryKeyRequest] importRecoveryKeyRequest (required): + Future importRecoveryKey(ImportRecoveryKeyRequest importRecoveryKeyRequest,) async { + final response = await importRecoveryKeyWithHttpInfo(importRecoveryKeyRequest,); + if (response.statusCode >= HttpStatus.badRequest) { + throw ApiException(response.statusCode, await _decodeBodyBytes(response)); + } + } + + /// Performs an HTTP 'GET /yucca/onboarding' operation and returns the [Response]. + Future onboardingStatusWithHttpInfo() async { + // ignore: prefer_const_declarations + final apiPath = r'/yucca/onboarding'; + + // ignore: prefer_final_locals + Object? postBody; + + final queryParams = []; + final headerParams = {}; + final formParams = {}; + + const contentTypes = []; + + + return apiClient.invokeAPI( + apiPath, + 'GET', + queryParams, + postBody, + headerParams, + formParams, + contentTypes.isEmpty ? null : contentTypes.first, + ); + } + + Future onboardingStatus() async { + final response = await onboardingStatusWithHttpInfo(); + 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), 'OnboardingStatusResponseDto',) as OnboardingStatusResponseDto; + + } + return null; + } + + /// Performs an HTTP 'POST /yucca/onboarding/skip' operation and returns the [Response]. + Future skipOnboardingExtraConfigWithHttpInfo() async { + // ignore: prefer_const_declarations + final apiPath = r'/yucca/onboarding/skip'; + + // ignore: prefer_final_locals + Object? postBody; + + final queryParams = []; + final headerParams = {}; + final formParams = {}; + + const contentTypes = []; + + + return apiClient.invokeAPI( + apiPath, + 'POST', + queryParams, + postBody, + headerParams, + formParams, + contentTypes.isEmpty ? null : contentTypes.first, + ); + } + + Future skipOnboardingExtraConfig() async { + final response = await skipOnboardingExtraConfigWithHttpInfo(); + if (response.statusCode >= HttpStatus.badRequest) { + throw ApiException(response.statusCode, await _decodeBodyBytes(response)); + } + } +} diff --git a/mobile/openapi/lib/api/repository_api.dart b/mobile/openapi/lib/api/repository_api.dart new file mode 100644 index 0000000000..c353223ad4 --- /dev/null +++ b/mobile/openapi/lib/api/repository_api.dart @@ -0,0 +1,701 @@ +// +// AUTO-GENERATED FILE, DO NOT MODIFY! +// +// @dart=2.18 + +// ignore_for_file: unused_element, unused_import +// ignore_for_file: always_put_required_named_parameters_first +// ignore_for_file: constant_identifier_names +// ignore_for_file: lines_longer_than_80_chars + +part of openapi.api; + + +class RepositoryApi { + RepositoryApi([ApiClient? apiClient]) : apiClient = apiClient ?? defaultApiClient; + + final ApiClient apiClient; + + /// Performs an HTTP 'GET /yucca/repository/{id}/import' operation and returns the [Response]. + /// Parameters: + /// + /// * [String] backend (required): + /// + /// * [String] id (required): + Future checkImportRepositoryWithHttpInfo(String backend, String id,) async { + // ignore: prefer_const_declarations + final apiPath = r'/yucca/repository/{id}/import' + .replaceAll('{id}', id); + + // ignore: prefer_final_locals + Object? postBody; + + final queryParams = []; + final headerParams = {}; + final formParams = {}; + + queryParams.addAll(_queryParams('', 'backend', backend)); + + const contentTypes = []; + + + return apiClient.invokeAPI( + apiPath, + 'GET', + queryParams, + postBody, + headerParams, + formParams, + contentTypes.isEmpty ? null : contentTypes.first, + ); + } + + /// Parameters: + /// + /// * [String] backend (required): + /// + /// * [String] id (required): + Future checkImportRepository(String backend, String id,) async { + final response = await checkImportRepositoryWithHttpInfo(backend, id,); + 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), 'RepositoryCheckImportResponseDto',) as RepositoryCheckImportResponseDto; + + } + return null; + } + + /// Performs an HTTP 'POST /yucca/repository/{id}' operation and returns the [Response]. + /// Parameters: + /// + /// * [String] id (required): + Future createBackupWithHttpInfo(String id,) async { + // ignore: prefer_const_declarations + final apiPath = r'/yucca/repository/{id}' + .replaceAll('{id}', id); + + // ignore: prefer_final_locals + Object? postBody; + + final queryParams = []; + final headerParams = {}; + final formParams = {}; + + const contentTypes = []; + + + return apiClient.invokeAPI( + apiPath, + 'POST', + queryParams, + postBody, + headerParams, + formParams, + contentTypes.isEmpty ? null : contentTypes.first, + ); + } + + /// Parameters: + /// + /// * [String] id (required): + Future createBackup(String id,) async { + final response = await createBackupWithHttpInfo(id,); + 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), 'LogResponseDto',) as LogResponseDto; + + } + return null; + } + + /// Performs an HTTP 'POST /yucca/repository' operation and returns the [Response]. + /// Parameters: + /// + /// * [RepositoryCreateRequestDto] repositoryCreateRequestDto (required): + /// + /// * [String] backend: + Future createRepositoryWithHttpInfo(RepositoryCreateRequestDto repositoryCreateRequestDto, { String? backend, }) async { + // ignore: prefer_const_declarations + final apiPath = r'/yucca/repository'; + + // ignore: prefer_final_locals + Object? postBody = repositoryCreateRequestDto; + + final queryParams = []; + final headerParams = {}; + final formParams = {}; + + if (backend != null) { + queryParams.addAll(_queryParams('', 'backend', backend)); + } + + const contentTypes = ['application/json']; + + + return apiClient.invokeAPI( + apiPath, + 'POST', + queryParams, + postBody, + headerParams, + formParams, + contentTypes.isEmpty ? null : contentTypes.first, + ); + } + + /// Parameters: + /// + /// * [RepositoryCreateRequestDto] repositoryCreateRequestDto (required): + /// + /// * [String] backend: + Future createRepository(RepositoryCreateRequestDto repositoryCreateRequestDto, { String? backend, }) async { + final response = await createRepositoryWithHttpInfo(repositoryCreateRequestDto, backend: backend, ); + 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), 'RepositoryCreateResponseDto',) as RepositoryCreateResponseDto; + + } + return null; + } + + /// Performs an HTTP 'DELETE /yucca/repository/{id}/snapshots/{snapshot}' operation and returns the [Response]. + /// Parameters: + /// + /// * [String] id (required): + /// + /// * [String] snapshot (required): + Future forgetSnapshotWithHttpInfo(String id, String snapshot,) async { + // ignore: prefer_const_declarations + final apiPath = r'/yucca/repository/{id}/snapshots/{snapshot}' + .replaceAll('{id}', id) + .replaceAll('{snapshot}', snapshot); + + // ignore: prefer_final_locals + Object? postBody; + + final queryParams = []; + final headerParams = {}; + final formParams = {}; + + const contentTypes = []; + + + return apiClient.invokeAPI( + apiPath, + 'DELETE', + queryParams, + postBody, + headerParams, + formParams, + contentTypes.isEmpty ? null : contentTypes.first, + ); + } + + /// Parameters: + /// + /// * [String] id (required): + /// + /// * [String] snapshot (required): + Future forgetSnapshot(String id, String snapshot,) async { + final response = await forgetSnapshotWithHttpInfo(id, snapshot,); + 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), 'ListSnapshotsResponseDto',) as ListSnapshotsResponseDto; + + } + return null; + } + + /// Performs an HTTP 'GET /yucca/repository' operation and returns the [Response]. + Future getRepositoriesWithHttpInfo() async { + // ignore: prefer_const_declarations + final apiPath = r'/yucca/repository'; + + // ignore: prefer_final_locals + Object? postBody; + + final queryParams = []; + final headerParams = {}; + final formParams = {}; + + const contentTypes = []; + + + return apiClient.invokeAPI( + apiPath, + 'GET', + queryParams, + postBody, + headerParams, + formParams, + contentTypes.isEmpty ? null : contentTypes.first, + ); + } + + Future getRepositories() async { + final response = await getRepositoriesWithHttpInfo(); + 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), 'RepositoryListResponseDto',) as RepositoryListResponseDto; + + } + return null; + } + + /// Performs an HTTP 'GET /yucca/repository/{id}/runs' operation and returns the [Response]. + /// Parameters: + /// + /// * [String] id (required): + Future getRunHistoryWithHttpInfo(String id,) async { + // ignore: prefer_const_declarations + final apiPath = r'/yucca/repository/{id}/runs' + .replaceAll('{id}', id); + + // ignore: prefer_final_locals + Object? postBody; + + final queryParams = []; + final headerParams = {}; + final formParams = {}; + + const contentTypes = []; + + + return apiClient.invokeAPI( + apiPath, + 'GET', + queryParams, + postBody, + headerParams, + formParams, + contentTypes.isEmpty ? null : contentTypes.first, + ); + } + + /// Parameters: + /// + /// * [String] id (required): + Future getRunHistory(String id,) async { + final response = await getRunHistoryWithHttpInfo(id,); + 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), 'RunHistoryResponseDto',) as RunHistoryResponseDto; + + } + return null; + } + + /// Performs an HTTP 'GET /yucca/repository/{id}/snapshots/{snapshot}/listing' operation and returns the [Response]. + /// Parameters: + /// + /// * [String] id (required): + /// + /// * [String] snapshot (required): + /// + /// * [String] path: + Future getSnapshotListingWithHttpInfo(String id, String snapshot, { String? path, }) async { + // ignore: prefer_const_declarations + final apiPath = r'/yucca/repository/{id}/snapshots/{snapshot}/listing' + .replaceAll('{id}', id) + .replaceAll('{snapshot}', snapshot); + + // ignore: prefer_final_locals + Object? postBody; + + final queryParams = []; + final headerParams = {}; + final formParams = {}; + + if (path != null) { + queryParams.addAll(_queryParams('', 'path', path)); + } + + const contentTypes = []; + + + return apiClient.invokeAPI( + apiPath, + 'GET', + queryParams, + postBody, + headerParams, + formParams, + contentTypes.isEmpty ? null : contentTypes.first, + ); + } + + /// Parameters: + /// + /// * [String] id (required): + /// + /// * [String] snapshot (required): + /// + /// * [String] path: + Future getSnapshotListing(String id, String snapshot, { String? path, }) async { + final response = await getSnapshotListingWithHttpInfo(id, snapshot, path: path, ); + 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), 'FilesystemListingResponseDto',) as FilesystemListingResponseDto; + + } + return null; + } + + /// Performs an HTTP 'GET /yucca/repository/{id}/snapshots' operation and returns the [Response]. + /// Parameters: + /// + /// * [String] id (required): + Future getSnapshotsWithHttpInfo(String id,) async { + // ignore: prefer_const_declarations + final apiPath = r'/yucca/repository/{id}/snapshots' + .replaceAll('{id}', id); + + // ignore: prefer_final_locals + Object? postBody; + + final queryParams = []; + final headerParams = {}; + final formParams = {}; + + const contentTypes = []; + + + return apiClient.invokeAPI( + apiPath, + 'GET', + queryParams, + postBody, + headerParams, + formParams, + contentTypes.isEmpty ? null : contentTypes.first, + ); + } + + /// Parameters: + /// + /// * [String] id (required): + Future getSnapshots(String id,) async { + final response = await getSnapshotsWithHttpInfo(id,); + 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), 'ListSnapshotsResponseDto',) as ListSnapshotsResponseDto; + + } + return null; + } + + /// Performs an HTTP 'POST /yucca/repository/{id}/import' operation and returns the [Response]. + /// Parameters: + /// + /// * [String] backend (required): + /// + /// * [String] id (required): + Future importRepositoryWithHttpInfo(String backend, String id,) async { + // ignore: prefer_const_declarations + final apiPath = r'/yucca/repository/{id}/import' + .replaceAll('{id}', id); + + // ignore: prefer_final_locals + Object? postBody; + + final queryParams = []; + final headerParams = {}; + final formParams = {}; + + queryParams.addAll(_queryParams('', 'backend', backend)); + + const contentTypes = []; + + + return apiClient.invokeAPI( + apiPath, + 'POST', + queryParams, + postBody, + headerParams, + formParams, + contentTypes.isEmpty ? null : contentTypes.first, + ); + } + + /// Parameters: + /// + /// * [String] backend (required): + /// + /// * [String] id (required): + Future importRepository(String backend, String id,) async { + final response = await importRepositoryWithHttpInfo(backend, id,); + 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), 'RepositoryCreateResponseDto',) as RepositoryCreateResponseDto; + + } + return null; + } + + /// Performs an HTTP 'GET /yucca/repository/inspect' operation and returns the [Response]. + Future inspectRepositoriesWithHttpInfo() async { + // ignore: prefer_const_declarations + final apiPath = r'/yucca/repository/inspect'; + + // ignore: prefer_final_locals + Object? postBody; + + final queryParams = []; + final headerParams = {}; + final formParams = {}; + + const contentTypes = []; + + + return apiClient.invokeAPI( + apiPath, + 'GET', + queryParams, + postBody, + headerParams, + formParams, + contentTypes.isEmpty ? null : contentTypes.first, + ); + } + + Future inspectRepositories() async { + final response = await inspectRepositoriesWithHttpInfo(); + 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), 'RepositoryInspectResponseDto',) as RepositoryInspectResponseDto; + + } + return null; + } + + /// Performs an HTTP 'POST /yucca/repository/{id}/snapshots/{snapshot}/restore-from-point' operation and returns the [Response]. + /// Parameters: + /// + /// * [String] backend (required): + /// + /// * [String] id (required): + /// + /// * [String] snapshot (required): + /// + /// * [RepositorySnapshotRestoreFromPointRequestDto] repositorySnapshotRestoreFromPointRequestDto (required): + Future restoreFromPointWithHttpInfo(String backend, String id, String snapshot, RepositorySnapshotRestoreFromPointRequestDto repositorySnapshotRestoreFromPointRequestDto,) async { + // ignore: prefer_const_declarations + final apiPath = r'/yucca/repository/{id}/snapshots/{snapshot}/restore-from-point' + .replaceAll('{id}', id) + .replaceAll('{snapshot}', snapshot); + + // ignore: prefer_final_locals + Object? postBody = repositorySnapshotRestoreFromPointRequestDto; + + final queryParams = []; + final headerParams = {}; + final formParams = {}; + + queryParams.addAll(_queryParams('', 'backend', backend)); + + const contentTypes = ['application/json']; + + + return apiClient.invokeAPI( + apiPath, + 'POST', + queryParams, + postBody, + headerParams, + formParams, + contentTypes.isEmpty ? null : contentTypes.first, + ); + } + + /// Parameters: + /// + /// * [String] backend (required): + /// + /// * [String] id (required): + /// + /// * [String] snapshot (required): + /// + /// * [RepositorySnapshotRestoreFromPointRequestDto] repositorySnapshotRestoreFromPointRequestDto (required): + Future restoreFromPoint(String backend, String id, String snapshot, RepositorySnapshotRestoreFromPointRequestDto repositorySnapshotRestoreFromPointRequestDto,) async { + final response = await restoreFromPointWithHttpInfo(backend, id, snapshot, repositorySnapshotRestoreFromPointRequestDto,); + 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), 'LogResponseDto',) as LogResponseDto; + + } + return null; + } + + /// Performs an HTTP 'POST /yucca/repository/{id}/snapshots/{snapshot}' operation and returns the [Response]. + /// Parameters: + /// + /// * [String] id (required): + /// + /// * [String] snapshot (required): + /// + /// * [RepositorySnapshotRestoreRequestDto] repositorySnapshotRestoreRequestDto (required): + Future restoreSnapshotWithHttpInfo(String id, String snapshot, RepositorySnapshotRestoreRequestDto repositorySnapshotRestoreRequestDto,) async { + // ignore: prefer_const_declarations + final apiPath = r'/yucca/repository/{id}/snapshots/{snapshot}' + .replaceAll('{id}', id) + .replaceAll('{snapshot}', snapshot); + + // ignore: prefer_final_locals + Object? postBody = repositorySnapshotRestoreRequestDto; + + final queryParams = []; + final headerParams = {}; + final formParams = {}; + + const contentTypes = ['application/json']; + + + return apiClient.invokeAPI( + apiPath, + 'POST', + queryParams, + postBody, + headerParams, + formParams, + contentTypes.isEmpty ? null : contentTypes.first, + ); + } + + /// Parameters: + /// + /// * [String] id (required): + /// + /// * [String] snapshot (required): + /// + /// * [RepositorySnapshotRestoreRequestDto] repositorySnapshotRestoreRequestDto (required): + Future restoreSnapshot(String id, String snapshot, RepositorySnapshotRestoreRequestDto repositorySnapshotRestoreRequestDto,) async { + final response = await restoreSnapshotWithHttpInfo(id, snapshot, repositorySnapshotRestoreRequestDto,); + 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), 'LogResponseDto',) as LogResponseDto; + + } + return null; + } + + /// Performs an HTTP 'PATCH /yucca/repository/{id}' operation and returns the [Response]. + /// Parameters: + /// + /// * [String] id (required): + /// + /// * [RepositoryUpdateRequestDto] repositoryUpdateRequestDto (required): + /// + /// * [String] backend: + Future updateRepositoryWithHttpInfo(String id, RepositoryUpdateRequestDto repositoryUpdateRequestDto, { String? backend, }) async { + // ignore: prefer_const_declarations + final apiPath = r'/yucca/repository/{id}' + .replaceAll('{id}', id); + + // ignore: prefer_final_locals + Object? postBody = repositoryUpdateRequestDto; + + final queryParams = []; + final headerParams = {}; + final formParams = {}; + + if (backend != null) { + queryParams.addAll(_queryParams('', 'backend', backend)); + } + + const contentTypes = ['application/json']; + + + return apiClient.invokeAPI( + apiPath, + 'PATCH', + queryParams, + postBody, + headerParams, + formParams, + contentTypes.isEmpty ? null : contentTypes.first, + ); + } + + /// Parameters: + /// + /// * [String] id (required): + /// + /// * [RepositoryUpdateRequestDto] repositoryUpdateRequestDto (required): + /// + /// * [String] backend: + Future updateRepository(String id, RepositoryUpdateRequestDto repositoryUpdateRequestDto, { String? backend, }) async { + final response = await updateRepositoryWithHttpInfo(id, repositoryUpdateRequestDto, backend: backend, ); + 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), 'RepositoryUpdateResponseDto',) as RepositoryUpdateResponseDto; + + } + return null; + } +} diff --git a/mobile/openapi/lib/api/run_history_api.dart b/mobile/openapi/lib/api/run_history_api.dart new file mode 100644 index 0000000000..0f116a1a83 --- /dev/null +++ b/mobile/openapi/lib/api/run_history_api.dart @@ -0,0 +1,58 @@ +// +// AUTO-GENERATED FILE, DO NOT MODIFY! +// +// @dart=2.18 + +// ignore_for_file: unused_element, unused_import +// ignore_for_file: always_put_required_named_parameters_first +// ignore_for_file: constant_identifier_names +// ignore_for_file: lines_longer_than_80_chars + +part of openapi.api; + + +class RunHistoryApi { + RunHistoryApi([ApiClient? apiClient]) : apiClient = apiClient ?? defaultApiClient; + + final ApiClient apiClient; + + /// Performs an HTTP 'GET /yucca/logs/{id}' operation and returns the [Response]. + /// Parameters: + /// + /// * [String] id (required): + Future logStreamSseWithHttpInfo(String id,) async { + // ignore: prefer_const_declarations + final apiPath = r'/yucca/logs/{id}' + .replaceAll('{id}', id); + + // ignore: prefer_final_locals + Object? postBody; + + final queryParams = []; + final headerParams = {}; + final formParams = {}; + + const contentTypes = []; + + + return apiClient.invokeAPI( + apiPath, + 'GET', + queryParams, + postBody, + headerParams, + formParams, + contentTypes.isEmpty ? null : contentTypes.first, + ); + } + + /// Parameters: + /// + /// * [String] id (required): + Future logStreamSse(String id,) async { + final response = await logStreamSseWithHttpInfo(id,); + if (response.statusCode >= HttpStatus.badRequest) { + throw ApiException(response.statusCode, await _decodeBodyBytes(response)); + } + } +} diff --git a/mobile/openapi/lib/api/running_tasks_api.dart b/mobile/openapi/lib/api/running_tasks_api.dart new file mode 100644 index 0000000000..94b78ab47c --- /dev/null +++ b/mobile/openapi/lib/api/running_tasks_api.dart @@ -0,0 +1,59 @@ +// +// AUTO-GENERATED FILE, DO NOT MODIFY! +// +// @dart=2.18 + +// ignore_for_file: unused_element, unused_import +// ignore_for_file: always_put_required_named_parameters_first +// ignore_for_file: constant_identifier_names +// ignore_for_file: lines_longer_than_80_chars + +part of openapi.api; + + +class RunningTasksApi { + RunningTasksApi([ApiClient? apiClient]) : apiClient = apiClient ?? defaultApiClient; + + final ApiClient apiClient; + + /// Performs an HTTP 'GET /yucca/tasks' operation and returns the [Response]. + Future getRunningTasksWithHttpInfo() async { + // ignore: prefer_const_declarations + final apiPath = r'/yucca/tasks'; + + // ignore: prefer_final_locals + Object? postBody; + + final queryParams = []; + final headerParams = {}; + final formParams = {}; + + const contentTypes = []; + + + return apiClient.invokeAPI( + apiPath, + 'GET', + queryParams, + postBody, + headerParams, + formParams, + contentTypes.isEmpty ? null : contentTypes.first, + ); + } + + Future getRunningTasks() async { + final response = await getRunningTasksWithHttpInfo(); + 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), 'RunningTaskListResponse',) as RunningTaskListResponse; + + } + return null; + } +} diff --git a/mobile/openapi/lib/api/schedule_api.dart b/mobile/openapi/lib/api/schedule_api.dart new file mode 100644 index 0000000000..84df95ce59 --- /dev/null +++ b/mobile/openapi/lib/api/schedule_api.dart @@ -0,0 +1,288 @@ +// +// AUTO-GENERATED FILE, DO NOT MODIFY! +// +// @dart=2.18 + +// ignore_for_file: unused_element, unused_import +// ignore_for_file: always_put_required_named_parameters_first +// ignore_for_file: constant_identifier_names +// ignore_for_file: lines_longer_than_80_chars + +part of openapi.api; + + +class ScheduleApi { + ScheduleApi([ApiClient? apiClient]) : apiClient = apiClient ?? defaultApiClient; + + final ApiClient apiClient; + + /// Performs an HTTP 'PUT /yucca/schedule/{id}/{repositoryId}' operation and returns the [Response]. + /// Parameters: + /// + /// * [String] id (required): + /// + /// * [String] repositoryId (required): + Future addRepositoryToScheduleWithHttpInfo(String id, String repositoryId,) async { + // ignore: prefer_const_declarations + final apiPath = r'/yucca/schedule/{id}/{repositoryId}' + .replaceAll('{id}', id) + .replaceAll('{repositoryId}', repositoryId); + + // ignore: prefer_final_locals + Object? postBody; + + final queryParams = []; + final headerParams = {}; + final formParams = {}; + + const contentTypes = []; + + + return apiClient.invokeAPI( + apiPath, + 'PUT', + queryParams, + postBody, + headerParams, + formParams, + contentTypes.isEmpty ? null : contentTypes.first, + ); + } + + /// Parameters: + /// + /// * [String] id (required): + /// + /// * [String] repositoryId (required): + Future addRepositoryToSchedule(String id, String repositoryId,) async { + final response = await addRepositoryToScheduleWithHttpInfo(id, repositoryId,); + if (response.statusCode >= HttpStatus.badRequest) { + throw ApiException(response.statusCode, await _decodeBodyBytes(response)); + } + } + + /// Performs an HTTP 'POST /yucca/schedule' operation and returns the [Response]. + /// Parameters: + /// + /// * [ScheduleCreateRequestDto] scheduleCreateRequestDto (required): + Future createScheduleWithHttpInfo(ScheduleCreateRequestDto scheduleCreateRequestDto,) async { + // ignore: prefer_const_declarations + final apiPath = r'/yucca/schedule'; + + // ignore: prefer_final_locals + Object? postBody = scheduleCreateRequestDto; + + final queryParams = []; + final headerParams = {}; + final formParams = {}; + + const contentTypes = ['application/json']; + + + return apiClient.invokeAPI( + apiPath, + 'POST', + queryParams, + postBody, + headerParams, + formParams, + contentTypes.isEmpty ? null : contentTypes.first, + ); + } + + /// Parameters: + /// + /// * [ScheduleCreateRequestDto] scheduleCreateRequestDto (required): + Future createSchedule(ScheduleCreateRequestDto scheduleCreateRequestDto,) async { + final response = await createScheduleWithHttpInfo(scheduleCreateRequestDto,); + 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), 'ScheduleCreateResponseDto',) as ScheduleCreateResponseDto; + + } + return null; + } + + /// Performs an HTTP 'GET /yucca/schedule' operation and returns the [Response]. + Future getSchedulesWithHttpInfo() async { + // ignore: prefer_const_declarations + final apiPath = r'/yucca/schedule'; + + // ignore: prefer_final_locals + Object? postBody; + + final queryParams = []; + final headerParams = {}; + final formParams = {}; + + const contentTypes = []; + + + return apiClient.invokeAPI( + apiPath, + 'GET', + queryParams, + postBody, + headerParams, + formParams, + contentTypes.isEmpty ? null : contentTypes.first, + ); + } + + Future getSchedules() async { + final response = await getSchedulesWithHttpInfo(); + 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), 'ScheduleListResponseDto',) as ScheduleListResponseDto; + + } + return null; + } + + /// Performs an HTTP 'DELETE /yucca/schedule/{id}/{repositoryId}' operation and returns the [Response]. + /// Parameters: + /// + /// * [String] id (required): + /// + /// * [String] repositoryId (required): + Future removeRepositoryFromScheduleWithHttpInfo(String id, String repositoryId,) async { + // ignore: prefer_const_declarations + final apiPath = r'/yucca/schedule/{id}/{repositoryId}' + .replaceAll('{id}', id) + .replaceAll('{repositoryId}', repositoryId); + + // ignore: prefer_final_locals + Object? postBody; + + final queryParams = []; + final headerParams = {}; + final formParams = {}; + + const contentTypes = []; + + + return apiClient.invokeAPI( + apiPath, + 'DELETE', + queryParams, + postBody, + headerParams, + formParams, + contentTypes.isEmpty ? null : contentTypes.first, + ); + } + + /// Parameters: + /// + /// * [String] id (required): + /// + /// * [String] repositoryId (required): + Future removeRepositoryFromSchedule(String id, String repositoryId,) async { + final response = await removeRepositoryFromScheduleWithHttpInfo(id, repositoryId,); + if (response.statusCode >= HttpStatus.badRequest) { + throw ApiException(response.statusCode, await _decodeBodyBytes(response)); + } + } + + /// Performs an HTTP 'DELETE /yucca/schedule/{id}' operation and returns the [Response]. + /// Parameters: + /// + /// * [String] id (required): + Future removeScheduleWithHttpInfo(String id,) async { + // ignore: prefer_const_declarations + final apiPath = r'/yucca/schedule/{id}' + .replaceAll('{id}', id); + + // ignore: prefer_final_locals + Object? postBody; + + final queryParams = []; + final headerParams = {}; + final formParams = {}; + + const contentTypes = []; + + + return apiClient.invokeAPI( + apiPath, + 'DELETE', + queryParams, + postBody, + headerParams, + formParams, + contentTypes.isEmpty ? null : contentTypes.first, + ); + } + + /// Parameters: + /// + /// * [String] id (required): + Future removeSchedule(String id,) async { + final response = await removeScheduleWithHttpInfo(id,); + if (response.statusCode >= HttpStatus.badRequest) { + throw ApiException(response.statusCode, await _decodeBodyBytes(response)); + } + } + + /// Performs an HTTP 'PATCH /yucca/schedule/{id}' operation and returns the [Response]. + /// Parameters: + /// + /// * [String] id (required): + /// + /// * [ScheduleUpdateRequestDto] scheduleUpdateRequestDto (required): + Future updateScheduleWithHttpInfo(String id, ScheduleUpdateRequestDto scheduleUpdateRequestDto,) async { + // ignore: prefer_const_declarations + final apiPath = r'/yucca/schedule/{id}' + .replaceAll('{id}', id); + + // ignore: prefer_final_locals + Object? postBody = scheduleUpdateRequestDto; + + final queryParams = []; + final headerParams = {}; + final formParams = {}; + + const contentTypes = ['application/json']; + + + return apiClient.invokeAPI( + apiPath, + 'PATCH', + queryParams, + postBody, + headerParams, + formParams, + contentTypes.isEmpty ? null : contentTypes.first, + ); + } + + /// Parameters: + /// + /// * [String] id (required): + /// + /// * [ScheduleUpdateRequestDto] scheduleUpdateRequestDto (required): + Future updateSchedule(String id, ScheduleUpdateRequestDto scheduleUpdateRequestDto,) async { + final response = await updateScheduleWithHttpInfo(id, scheduleUpdateRequestDto,); + 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), 'ScheduleUpdateResponseDto',) as ScheduleUpdateResponseDto; + + } + return null; + } +} diff --git a/mobile/openapi/lib/api_client.dart b/mobile/openapi/lib/api_client.dart index 3ed1f7529f..1119e0e585 100644 --- a/mobile/openapi/lib/api_client.dart +++ b/mobile/openapi/lib/api_client.dart @@ -190,6 +190,8 @@ class ApiClient { return APIKeyResponseDto.fromJson(value); case 'APIKeyUpdateDto': return APIKeyUpdateDto.fromJson(value); + case 'ActiveScheduleItemDto': + return ActiveScheduleItemDto.fromJson(value); case 'ActivityCreateDto': return ActivityCreateDto.fromJson(value); case 'ActivityResponseDto': @@ -320,6 +322,14 @@ class ApiClient { return AuthStatusResponseDto.fromJson(value); case 'AvatarUpdate': return AvatarUpdate.fromJson(value); + case 'BackendDto': + return BackendDto.fromJson(value); + case 'BackendResponseDto': + return BackendResponseDto.fromJson(value); + case 'BackendType': + return BackendTypeTypeTransformer().decode(value); + case 'BackendsResponseDto': + return BackendsResponseDto.fromJson(value); case 'BulkIdErrorReason': return BulkIdErrorReasonTypeTransformer().decode(value); case 'BulkIdResponseDto': @@ -342,16 +352,24 @@ class ApiClient { return CheckExistingAssetsResponseDto.fromJson(value); case 'Colorspace': return ColorspaceTypeTransformer().decode(value); + case 'ConfigureImmichIntegrationRequestDto': + return ConfigureImmichIntegrationRequestDto.fromJson(value); + case 'ConfigureImmichIntegrationRequestDtoLibraries': + return ConfigureImmichIntegrationRequestDtoLibraries.fromJson(value); case 'ContributorCountResponseDto': return ContributorCountResponseDto.fromJson(value); case 'CreateAlbumDto': return CreateAlbumDto.fromJson(value); case 'CreateLibraryDto': return CreateLibraryDto.fromJson(value); + case 'CreateLocalBackendRequestDto': + return CreateLocalBackendRequestDto.fromJson(value); case 'CreateProfileImageResponseDto': return CreateProfileImageResponseDto.fromJson(value); case 'CropParameters': return CropParameters.fromJson(value); + case 'CurrentRecoveryKeyResponse': + return CurrentRecoveryKeyResponse.fromJson(value); case 'DatabaseBackupConfig': return DatabaseBackupConfig.fromJson(value); case 'DatabaseBackupDeleteDto': @@ -390,12 +408,30 @@ class ApiClient { return FaceDto.fromJson(value); case 'FacialRecognitionConfig': return FacialRecognitionConfig.fromJson(value); + case 'FilesystemListingItemDto': + return FilesystemListingItemDto.fromJson(value); + case 'FilesystemListingResponseDto': + return FilesystemListingResponseDto.fromJson(value); case 'FoldersResponse': return FoldersResponse.fromJson(value); case 'FoldersUpdate': return FoldersUpdate.fromJson(value); case 'ImageFormat': return ImageFormatTypeTransformer().decode(value); + case 'ImmichIntegrationConfigurationDto': + return ImmichIntegrationConfigurationDto.fromJson(value); + case 'ImmichIntegrationDto': + return ImmichIntegrationDto.fromJson(value); + case 'ImmichLibraryDto': + return ImmichLibraryDto.fromJson(value); + case 'ImmichStateDto': + return ImmichStateDto.fromJson(value); + case 'ImportRecoveryKeyRequest': + return ImportRecoveryKeyRequest.fromJson(value); + case 'InspectedLocalRepositoryDto': + return InspectedLocalRepositoryDto.fromJson(value); + case 'IntegrationsResponseDto': + return IntegrationsResponseDto.fromJson(value); case 'JobCreateDto': return JobCreateDto.fromJson(value); case 'JobName': @@ -408,8 +444,14 @@ class ApiClient { return LibraryStatsResponseDto.fromJson(value); case 'LicenseKeyDto': return LicenseKeyDto.fromJson(value); + case 'ListSnapshotsResponseDto': + return ListSnapshotsResponseDto.fromJson(value); + case 'LocalRepositoryDto': + return LocalRepositoryDto.fromJson(value); case 'LogLevel': return LogLevelTypeTransformer().decode(value); + case 'LogResponseDto': + return LogResponseDto.fromJson(value); case 'LoginCredentialDto': return LoginCredentialDto.fromJson(value); case 'LoginResponseDto': @@ -490,6 +532,8 @@ class ApiClient { return OnboardingDto.fromJson(value); case 'OnboardingResponseDto': return OnboardingResponseDto.fromJson(value); + case 'OnboardingStatusResponseDto': + return OnboardingStatusResponseDto.fromJson(value); case 'PartnerCreateDto': return PartnerCreateDto.fromJson(value); case 'PartnerDirection': @@ -586,10 +630,58 @@ class ApiClient { return ReactionLevelTypeTransformer().decode(value); case 'ReactionType': return ReactionTypeTypeTransformer().decode(value); + case 'RepositoryBackendDto': + return RepositoryBackendDto.fromJson(value); + case 'RepositoryBackendsDto': + return RepositoryBackendsDto.fromJson(value); + case 'RepositoryCheckImportResponseDto': + return RepositoryCheckImportResponseDto.fromJson(value); + case 'RepositoryConfigurationDto': + return RepositoryConfigurationDto.fromJson(value); + case 'RepositoryCreateRequestDto': + return RepositoryCreateRequestDto.fromJson(value); + case 'RepositoryCreateResponseDto': + return RepositoryCreateResponseDto.fromJson(value); + case 'RepositoryInspectResponseDto': + return RepositoryInspectResponseDto.fromJson(value); + case 'RepositoryListResponseDto': + return RepositoryListResponseDto.fromJson(value); + case 'RepositoryMetricsDto': + return RepositoryMetricsDto.fromJson(value); + case 'RepositorySnapshotRestoreFromPointRequestDto': + return RepositorySnapshotRestoreFromPointRequestDto.fromJson(value); + case 'RepositorySnapshotRestoreRequestDto': + return RepositorySnapshotRestoreRequestDto.fromJson(value); + case 'RepositoryUpdateRequestDto': + return RepositoryUpdateRequestDto.fromJson(value); + case 'RepositoryUpdateResponseDto': + return RepositoryUpdateResponseDto.fromJson(value); case 'ReverseGeocodingStateResponseDto': return ReverseGeocodingStateResponseDto.fromJson(value); case 'RotateParameters': return RotateParameters.fromJson(value); + case 'RunDto': + return RunDto.fromJson(value); + case 'RunHistoryResponseDto': + return RunHistoryResponseDto.fromJson(value); + case 'RunStatus': + return RunStatusTypeTransformer().decode(value); + case 'RunningTaskDto': + return RunningTaskDto.fromJson(value); + case 'RunningTaskListResponse': + return RunningTaskListResponse.fromJson(value); + case 'ScheduleCreateRequestDto': + return ScheduleCreateRequestDto.fromJson(value); + case 'ScheduleCreateResponseDto': + return ScheduleCreateResponseDto.fromJson(value); + case 'ScheduleDto': + return ScheduleDto.fromJson(value); + case 'ScheduleListResponseDto': + return ScheduleListResponseDto.fromJson(value); + case 'ScheduleUpdateRequestDto': + return ScheduleUpdateRequestDto.fromJson(value); + case 'ScheduleUpdateResponseDto': + return ScheduleUpdateResponseDto.fromJson(value); case 'SearchAlbumResponseDto': return SearchAlbumResponseDto.fromJson(value); case 'SearchAssetResponseDto': @@ -660,6 +752,8 @@ class ApiClient { return SignUpDto.fromJson(value); case 'SmartSearchDto': return SmartSearchDto.fromJson(value); + case 'SnapshotDto': + return SnapshotDto.fromJson(value); case 'SourceType': return SourceTypeTypeTransformer().decode(value); case 'StackCreateDto': @@ -824,6 +918,10 @@ class ApiClient { return TagsResponse.fromJson(value); case 'TagsUpdate': return TagsUpdate.fromJson(value); + case 'TaskStatus': + return TaskStatusTypeTransformer().decode(value); + case 'TaskType': + return TaskTypeTypeTransformer().decode(value); case 'TemplateDto': return TemplateDto.fromJson(value); case 'TemplateResponseDto': diff --git a/mobile/openapi/lib/api_helper.dart b/mobile/openapi/lib/api_helper.dart index 3b36b23d6c..8c51f90473 100644 --- a/mobile/openapi/lib/api_helper.dart +++ b/mobile/openapi/lib/api_helper.dart @@ -91,6 +91,9 @@ String parameterToString(dynamic value) { if (value is AudioCodec) { return AudioCodecTypeTransformer().encode(value).toString(); } + if (value is BackendType) { + return BackendTypeTypeTransformer().encode(value).toString(); + } if (value is BulkIdErrorReason) { return BulkIdErrorReasonTypeTransformer().encode(value).toString(); } @@ -163,6 +166,9 @@ String parameterToString(dynamic value) { if (value is ReactionType) { return ReactionTypeTypeTransformer().encode(value).toString(); } + if (value is RunStatus) { + return RunStatusTypeTransformer().encode(value).toString(); + } if (value is SearchSuggestionType) { return SearchSuggestionTypeTypeTransformer().encode(value).toString(); } @@ -181,6 +187,12 @@ String parameterToString(dynamic value) { if (value is SyncRequestType) { return SyncRequestTypeTypeTransformer().encode(value).toString(); } + if (value is TaskStatus) { + return TaskStatusTypeTransformer().encode(value).toString(); + } + if (value is TaskType) { + return TaskTypeTypeTransformer().encode(value).toString(); + } if (value is ToneMapping) { return ToneMappingTypeTransformer().encode(value).toString(); } diff --git a/mobile/openapi/lib/model/active_schedule_item_dto.dart b/mobile/openapi/lib/model/active_schedule_item_dto.dart new file mode 100644 index 0000000000..068d1579be --- /dev/null +++ b/mobile/openapi/lib/model/active_schedule_item_dto.dart @@ -0,0 +1,107 @@ +// +// AUTO-GENERATED FILE, DO NOT MODIFY! +// +// @dart=2.18 + +// ignore_for_file: unused_element, unused_import +// ignore_for_file: always_put_required_named_parameters_first +// ignore_for_file: constant_identifier_names +// ignore_for_file: lines_longer_than_80_chars + +part of openapi.api; + +class ActiveScheduleItemDto { + /// Returns a new [ActiveScheduleItemDto] instance. + ActiveScheduleItemDto({ + required this.repositoryId, + required this.status, + }); + + String repositoryId; + + TaskStatus status; + + @override + bool operator ==(Object other) => identical(this, other) || other is ActiveScheduleItemDto && + other.repositoryId == repositoryId && + other.status == status; + + @override + int get hashCode => + // ignore: unnecessary_parenthesis + (repositoryId.hashCode) + + (status.hashCode); + + @override + String toString() => 'ActiveScheduleItemDto[repositoryId=$repositoryId, status=$status]'; + + Map toJson() { + final json = {}; + json[r'repositoryId'] = this.repositoryId; + json[r'status'] = this.status; + return json; + } + + /// Returns a new [ActiveScheduleItemDto] instance and imports its values from + /// [value] if it's a [Map], null otherwise. + // ignore: prefer_constructors_over_static_methods + static ActiveScheduleItemDto? fromJson(dynamic value) { + upgradeDto(value, "ActiveScheduleItemDto"); + if (value is Map) { + final json = value.cast(); + + return ActiveScheduleItemDto( + repositoryId: mapValueOfType(json, r'repositoryId')!, + status: TaskStatus.fromJson(json[r'status'])!, + ); + } + 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 = ActiveScheduleItemDto.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 = ActiveScheduleItemDto.fromJson(entry.value); + if (value != null) { + map[entry.key] = value; + } + } + } + return map; + } + + // maps a json object with a list of ActiveScheduleItemDto-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] = ActiveScheduleItemDto.listFromJson(entry.value, growable: growable,); + } + } + return map; + } + + /// The list of required keys that must be present in a JSON. + static const requiredKeys = { + 'repositoryId', + 'status', + }; +} + diff --git a/mobile/openapi/lib/model/backend_dto.dart b/mobile/openapi/lib/model/backend_dto.dart new file mode 100644 index 0000000000..28b6b94b18 --- /dev/null +++ b/mobile/openapi/lib/model/backend_dto.dart @@ -0,0 +1,132 @@ +// +// AUTO-GENERATED FILE, DO NOT MODIFY! +// +// @dart=2.18 + +// ignore_for_file: unused_element, unused_import +// ignore_for_file: always_put_required_named_parameters_first +// ignore_for_file: constant_identifier_names +// ignore_for_file: lines_longer_than_80_chars + +part of openapi.api; + +class BackendDto { + /// Returns a new [BackendDto] instance. + BackendDto({ + this.error, + required this.id, + required this.isOnline, + required this.type, + }); + + /// + /// 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? error; + + String id; + + bool isOnline; + + BackendType type; + + @override + bool operator ==(Object other) => identical(this, other) || other is BackendDto && + other.error == error && + other.id == id && + other.isOnline == isOnline && + other.type == type; + + @override + int get hashCode => + // ignore: unnecessary_parenthesis + (error == null ? 0 : error!.hashCode) + + (id.hashCode) + + (isOnline.hashCode) + + (type.hashCode); + + @override + String toString() => 'BackendDto[error=$error, id=$id, isOnline=$isOnline, type=$type]'; + + Map toJson() { + final json = {}; + if (this.error != null) { + json[r'error'] = this.error; + } else { + // json[r'error'] = null; + } + json[r'id'] = this.id; + json[r'isOnline'] = this.isOnline; + json[r'type'] = this.type; + return json; + } + + /// Returns a new [BackendDto] instance and imports its values from + /// [value] if it's a [Map], null otherwise. + // ignore: prefer_constructors_over_static_methods + static BackendDto? fromJson(dynamic value) { + upgradeDto(value, "BackendDto"); + if (value is Map) { + final json = value.cast(); + + return BackendDto( + error: mapValueOfType(json, r'error'), + id: mapValueOfType(json, r'id')!, + isOnline: mapValueOfType(json, r'isOnline')!, + type: BackendType.fromJson(json[r'type'])!, + ); + } + 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 = BackendDto.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 = BackendDto.fromJson(entry.value); + if (value != null) { + map[entry.key] = value; + } + } + } + return map; + } + + // maps a json object with a list of BackendDto-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] = BackendDto.listFromJson(entry.value, growable: growable,); + } + } + return map; + } + + /// The list of required keys that must be present in a JSON. + static const requiredKeys = { + 'id', + 'isOnline', + 'type', + }; +} + diff --git a/mobile/openapi/lib/model/backend_response_dto.dart b/mobile/openapi/lib/model/backend_response_dto.dart new file mode 100644 index 0000000000..bf52728b1f --- /dev/null +++ b/mobile/openapi/lib/model/backend_response_dto.dart @@ -0,0 +1,99 @@ +// +// AUTO-GENERATED FILE, DO NOT MODIFY! +// +// @dart=2.18 + +// ignore_for_file: unused_element, unused_import +// ignore_for_file: always_put_required_named_parameters_first +// ignore_for_file: constant_identifier_names +// ignore_for_file: lines_longer_than_80_chars + +part of openapi.api; + +class BackendResponseDto { + /// Returns a new [BackendResponseDto] instance. + BackendResponseDto({ + required this.backend, + }); + + BackendDto backend; + + @override + bool operator ==(Object other) => identical(this, other) || other is BackendResponseDto && + other.backend == backend; + + @override + int get hashCode => + // ignore: unnecessary_parenthesis + (backend.hashCode); + + @override + String toString() => 'BackendResponseDto[backend=$backend]'; + + Map toJson() { + final json = {}; + json[r'backend'] = this.backend; + return json; + } + + /// Returns a new [BackendResponseDto] instance and imports its values from + /// [value] if it's a [Map], null otherwise. + // ignore: prefer_constructors_over_static_methods + static BackendResponseDto? fromJson(dynamic value) { + upgradeDto(value, "BackendResponseDto"); + if (value is Map) { + final json = value.cast(); + + return BackendResponseDto( + backend: BackendDto.fromJson(json[r'backend'])!, + ); + } + 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 = BackendResponseDto.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 = BackendResponseDto.fromJson(entry.value); + if (value != null) { + map[entry.key] = value; + } + } + } + return map; + } + + // maps a json object with a list of BackendResponseDto-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] = BackendResponseDto.listFromJson(entry.value, growable: growable,); + } + } + return map; + } + + /// The list of required keys that must be present in a JSON. + static const requiredKeys = { + 'backend', + }; +} + diff --git a/mobile/openapi/lib/model/backend_type.dart b/mobile/openapi/lib/model/backend_type.dart new file mode 100644 index 0000000000..cacf63ae17 --- /dev/null +++ b/mobile/openapi/lib/model/backend_type.dart @@ -0,0 +1,88 @@ +// +// AUTO-GENERATED FILE, DO NOT MODIFY! +// +// @dart=2.18 + +// ignore_for_file: unused_element, unused_import +// ignore_for_file: always_put_required_named_parameters_first +// ignore_for_file: constant_identifier_names +// ignore_for_file: lines_longer_than_80_chars + +part of openapi.api; + + +class BackendType { + /// Instantiate a new enum with the provided [value]. + const BackendType._(this.value); + + /// The underlying value of this enum member. + final String value; + + @override + String toString() => value; + + String toJson() => value; + + static const yucca = BackendType._(r'yucca'); + static const local = BackendType._(r'local'); + static const s3 = BackendType._(r's3'); + + /// List of all possible values in this [enum][BackendType]. + static const values = [ + yucca, + local, + s3, + ]; + + static BackendType? fromJson(dynamic value) => BackendTypeTypeTransformer().decode(value); + + static List listFromJson(dynamic json, {bool growable = false,}) { + final result = []; + if (json is List && json.isNotEmpty) { + for (final row in json) { + final value = BackendType.fromJson(row); + if (value != null) { + result.add(value); + } + } + } + return result.toList(growable: growable); + } +} + +/// Transformation class that can [encode] an instance of [BackendType] to String, +/// and [decode] dynamic data back to [BackendType]. +class BackendTypeTypeTransformer { + factory BackendTypeTypeTransformer() => _instance ??= const BackendTypeTypeTransformer._(); + + const BackendTypeTypeTransformer._(); + + String encode(BackendType data) => data.value; + + /// Decodes a [dynamic value][data] to a BackendType. + /// + /// If [allowNull] is true and the [dynamic value][data] cannot be decoded successfully, + /// then null is returned. However, if [allowNull] is false and the [dynamic value][data] + /// cannot be decoded successfully, then an [UnimplementedError] is thrown. + /// + /// The [allowNull] is very handy when an API changes and a new enum value is added or removed, + /// and users are still using an old app with the old code. + BackendType? decode(dynamic data, {bool allowNull = true}) { + if (data != null) { + switch (data) { + case r'yucca': return BackendType.yucca; + case r'local': return BackendType.local; + case r's3': return BackendType.s3; + default: + if (!allowNull) { + throw ArgumentError('Unknown enum value to decode: $data'); + } + } + } + return null; + } + + /// Singleton [BackendTypeTypeTransformer] instance. + static BackendTypeTypeTransformer? _instance; +} + diff --git a/mobile/openapi/lib/model/backends_response_dto.dart b/mobile/openapi/lib/model/backends_response_dto.dart new file mode 100644 index 0000000000..e47b1cd51a --- /dev/null +++ b/mobile/openapi/lib/model/backends_response_dto.dart @@ -0,0 +1,99 @@ +// +// AUTO-GENERATED FILE, DO NOT MODIFY! +// +// @dart=2.18 + +// ignore_for_file: unused_element, unused_import +// ignore_for_file: always_put_required_named_parameters_first +// ignore_for_file: constant_identifier_names +// ignore_for_file: lines_longer_than_80_chars + +part of openapi.api; + +class BackendsResponseDto { + /// Returns a new [BackendsResponseDto] instance. + BackendsResponseDto({ + this.backends = const [], + }); + + List backends; + + @override + bool operator ==(Object other) => identical(this, other) || other is BackendsResponseDto && + _deepEquality.equals(other.backends, backends); + + @override + int get hashCode => + // ignore: unnecessary_parenthesis + (backends.hashCode); + + @override + String toString() => 'BackendsResponseDto[backends=$backends]'; + + Map toJson() { + final json = {}; + json[r'backends'] = this.backends; + return json; + } + + /// Returns a new [BackendsResponseDto] instance and imports its values from + /// [value] if it's a [Map], null otherwise. + // ignore: prefer_constructors_over_static_methods + static BackendsResponseDto? fromJson(dynamic value) { + upgradeDto(value, "BackendsResponseDto"); + if (value is Map) { + final json = value.cast(); + + return BackendsResponseDto( + backends: BackendDto.listFromJson(json[r'backends']), + ); + } + 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 = BackendsResponseDto.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 = BackendsResponseDto.fromJson(entry.value); + if (value != null) { + map[entry.key] = value; + } + } + } + return map; + } + + // maps a json object with a list of BackendsResponseDto-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] = BackendsResponseDto.listFromJson(entry.value, growable: growable,); + } + } + return map; + } + + /// The list of required keys that must be present in a JSON. + static const requiredKeys = { + 'backends', + }; +} + diff --git a/mobile/openapi/lib/model/configure_immich_integration_request_dto.dart b/mobile/openapi/lib/model/configure_immich_integration_request_dto.dart new file mode 100644 index 0000000000..aa5f475190 --- /dev/null +++ b/mobile/openapi/lib/model/configure_immich_integration_request_dto.dart @@ -0,0 +1,141 @@ +// +// AUTO-GENERATED FILE, DO NOT MODIFY! +// +// @dart=2.18 + +// ignore_for_file: unused_element, unused_import +// ignore_for_file: always_put_required_named_parameters_first +// ignore_for_file: constant_identifier_names +// ignore_for_file: lines_longer_than_80_chars + +part of openapi.api; + +class ConfigureImmichIntegrationRequestDto { + /// Returns a new [ConfigureImmichIntegrationRequestDto] instance. + ConfigureImmichIntegrationRequestDto({ + required this.backupConfiguration, + required this.cron, + this.dataFolders = const [], + required this.libraries, + required this.name, + required this.worm, + }); + + bool backupConfiguration; + + String cron; + + List dataFolders; + + ConfigureImmichIntegrationRequestDtoLibraries libraries; + + String name; + + bool worm; + + @override + bool operator ==(Object other) => identical(this, other) || other is ConfigureImmichIntegrationRequestDto && + other.backupConfiguration == backupConfiguration && + other.cron == cron && + _deepEquality.equals(other.dataFolders, dataFolders) && + other.libraries == libraries && + other.name == name && + other.worm == worm; + + @override + int get hashCode => + // ignore: unnecessary_parenthesis + (backupConfiguration.hashCode) + + (cron.hashCode) + + (dataFolders.hashCode) + + (libraries.hashCode) + + (name.hashCode) + + (worm.hashCode); + + @override + String toString() => 'ConfigureImmichIntegrationRequestDto[backupConfiguration=$backupConfiguration, cron=$cron, dataFolders=$dataFolders, libraries=$libraries, name=$name, worm=$worm]'; + + Map toJson() { + final json = {}; + json[r'backupConfiguration'] = this.backupConfiguration; + json[r'cron'] = this.cron; + json[r'dataFolders'] = this.dataFolders; + json[r'libraries'] = this.libraries; + json[r'name'] = this.name; + json[r'worm'] = this.worm; + return json; + } + + /// Returns a new [ConfigureImmichIntegrationRequestDto] instance and imports its values from + /// [value] if it's a [Map], null otherwise. + // ignore: prefer_constructors_over_static_methods + static ConfigureImmichIntegrationRequestDto? fromJson(dynamic value) { + upgradeDto(value, "ConfigureImmichIntegrationRequestDto"); + if (value is Map) { + final json = value.cast(); + + return ConfigureImmichIntegrationRequestDto( + backupConfiguration: mapValueOfType(json, r'backupConfiguration')!, + cron: mapValueOfType(json, r'cron')!, + dataFolders: json[r'dataFolders'] is Iterable + ? (json[r'dataFolders'] as Iterable).cast().toList(growable: false) + : const [], + libraries: ConfigureImmichIntegrationRequestDtoLibraries.fromJson(json[r'libraries'])!, + name: mapValueOfType(json, r'name')!, + worm: mapValueOfType(json, r'worm')!, + ); + } + 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 = ConfigureImmichIntegrationRequestDto.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 = ConfigureImmichIntegrationRequestDto.fromJson(entry.value); + if (value != null) { + map[entry.key] = value; + } + } + } + return map; + } + + // maps a json object with a list of ConfigureImmichIntegrationRequestDto-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] = ConfigureImmichIntegrationRequestDto.listFromJson(entry.value, growable: growable,); + } + } + return map; + } + + /// The list of required keys that must be present in a JSON. + static const requiredKeys = { + 'backupConfiguration', + 'cron', + 'dataFolders', + 'libraries', + 'name', + 'worm', + }; +} + diff --git a/mobile/openapi/lib/model/configure_immich_integration_request_dto_libraries.dart b/mobile/openapi/lib/model/configure_immich_integration_request_dto_libraries.dart new file mode 100644 index 0000000000..7477b95621 --- /dev/null +++ b/mobile/openapi/lib/model/configure_immich_integration_request_dto_libraries.dart @@ -0,0 +1,91 @@ +// +// AUTO-GENERATED FILE, DO NOT MODIFY! +// +// @dart=2.18 + +// ignore_for_file: unused_element, unused_import +// ignore_for_file: always_put_required_named_parameters_first +// ignore_for_file: constant_identifier_names +// ignore_for_file: lines_longer_than_80_chars + +part of openapi.api; + +class ConfigureImmichIntegrationRequestDtoLibraries { + /// Returns a new [ConfigureImmichIntegrationRequestDtoLibraries] instance. + ConfigureImmichIntegrationRequestDtoLibraries({ + }); + + @override + bool operator ==(Object other) => identical(this, other) || other is ConfigureImmichIntegrationRequestDtoLibraries && + + @override + int get hashCode => + // ignore: unnecessary_parenthesis + + @override + String toString() => 'ConfigureImmichIntegrationRequestDtoLibraries[]'; + + Map toJson() { + final json = {}; + return json; + } + + /// Returns a new [ConfigureImmichIntegrationRequestDtoLibraries] instance and imports its values from + /// [value] if it's a [Map], null otherwise. + // ignore: prefer_constructors_over_static_methods + static ConfigureImmichIntegrationRequestDtoLibraries? fromJson(dynamic value) { + upgradeDto(value, "ConfigureImmichIntegrationRequestDtoLibraries"); + if (value is Map) { + final json = value.cast(); + + return ConfigureImmichIntegrationRequestDtoLibraries( + ); + } + 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 = ConfigureImmichIntegrationRequestDtoLibraries.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 = ConfigureImmichIntegrationRequestDtoLibraries.fromJson(entry.value); + if (value != null) { + map[entry.key] = value; + } + } + } + return map; + } + + // maps a json object with a list of ConfigureImmichIntegrationRequestDtoLibraries-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] = ConfigureImmichIntegrationRequestDtoLibraries.listFromJson(entry.value, growable: growable,); + } + } + return map; + } + + /// The list of required keys that must be present in a JSON. + static const requiredKeys = { + }; +} + diff --git a/mobile/openapi/lib/model/create_local_backend_request_dto.dart b/mobile/openapi/lib/model/create_local_backend_request_dto.dart new file mode 100644 index 0000000000..56ae304878 --- /dev/null +++ b/mobile/openapi/lib/model/create_local_backend_request_dto.dart @@ -0,0 +1,99 @@ +// +// AUTO-GENERATED FILE, DO NOT MODIFY! +// +// @dart=2.18 + +// ignore_for_file: unused_element, unused_import +// ignore_for_file: always_put_required_named_parameters_first +// ignore_for_file: constant_identifier_names +// ignore_for_file: lines_longer_than_80_chars + +part of openapi.api; + +class CreateLocalBackendRequestDto { + /// Returns a new [CreateLocalBackendRequestDto] instance. + CreateLocalBackendRequestDto({ + required this.path, + }); + + String path; + + @override + bool operator ==(Object other) => identical(this, other) || other is CreateLocalBackendRequestDto && + other.path == path; + + @override + int get hashCode => + // ignore: unnecessary_parenthesis + (path.hashCode); + + @override + String toString() => 'CreateLocalBackendRequestDto[path=$path]'; + + Map toJson() { + final json = {}; + json[r'path'] = this.path; + return json; + } + + /// Returns a new [CreateLocalBackendRequestDto] instance and imports its values from + /// [value] if it's a [Map], null otherwise. + // ignore: prefer_constructors_over_static_methods + static CreateLocalBackendRequestDto? fromJson(dynamic value) { + upgradeDto(value, "CreateLocalBackendRequestDto"); + if (value is Map) { + final json = value.cast(); + + return CreateLocalBackendRequestDto( + path: mapValueOfType(json, r'path')!, + ); + } + 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 = CreateLocalBackendRequestDto.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 = CreateLocalBackendRequestDto.fromJson(entry.value); + if (value != null) { + map[entry.key] = value; + } + } + } + return map; + } + + // maps a json object with a list of CreateLocalBackendRequestDto-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] = CreateLocalBackendRequestDto.listFromJson(entry.value, growable: growable,); + } + } + return map; + } + + /// The list of required keys that must be present in a JSON. + static const requiredKeys = { + 'path', + }; +} + diff --git a/mobile/openapi/lib/model/current_recovery_key_response.dart b/mobile/openapi/lib/model/current_recovery_key_response.dart new file mode 100644 index 0000000000..10ff2bef94 --- /dev/null +++ b/mobile/openapi/lib/model/current_recovery_key_response.dart @@ -0,0 +1,99 @@ +// +// AUTO-GENERATED FILE, DO NOT MODIFY! +// +// @dart=2.18 + +// ignore_for_file: unused_element, unused_import +// ignore_for_file: always_put_required_named_parameters_first +// ignore_for_file: constant_identifier_names +// ignore_for_file: lines_longer_than_80_chars + +part of openapi.api; + +class CurrentRecoveryKeyResponse { + /// Returns a new [CurrentRecoveryKeyResponse] instance. + CurrentRecoveryKeyResponse({ + required this.recoveryKey, + }); + + String recoveryKey; + + @override + bool operator ==(Object other) => identical(this, other) || other is CurrentRecoveryKeyResponse && + other.recoveryKey == recoveryKey; + + @override + int get hashCode => + // ignore: unnecessary_parenthesis + (recoveryKey.hashCode); + + @override + String toString() => 'CurrentRecoveryKeyResponse[recoveryKey=$recoveryKey]'; + + Map toJson() { + final json = {}; + json[r'recoveryKey'] = this.recoveryKey; + return json; + } + + /// Returns a new [CurrentRecoveryKeyResponse] instance and imports its values from + /// [value] if it's a [Map], null otherwise. + // ignore: prefer_constructors_over_static_methods + static CurrentRecoveryKeyResponse? fromJson(dynamic value) { + upgradeDto(value, "CurrentRecoveryKeyResponse"); + if (value is Map) { + final json = value.cast(); + + return CurrentRecoveryKeyResponse( + recoveryKey: mapValueOfType(json, r'recoveryKey')!, + ); + } + 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 = CurrentRecoveryKeyResponse.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 = CurrentRecoveryKeyResponse.fromJson(entry.value); + if (value != null) { + map[entry.key] = value; + } + } + } + return map; + } + + // maps a json object with a list of CurrentRecoveryKeyResponse-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] = CurrentRecoveryKeyResponse.listFromJson(entry.value, growable: growable,); + } + } + return map; + } + + /// The list of required keys that must be present in a JSON. + static const requiredKeys = { + 'recoveryKey', + }; +} + diff --git a/mobile/openapi/lib/model/filesystem_listing_item_dto.dart b/mobile/openapi/lib/model/filesystem_listing_item_dto.dart new file mode 100644 index 0000000000..5366901ba4 --- /dev/null +++ b/mobile/openapi/lib/model/filesystem_listing_item_dto.dart @@ -0,0 +1,107 @@ +// +// AUTO-GENERATED FILE, DO NOT MODIFY! +// +// @dart=2.18 + +// ignore_for_file: unused_element, unused_import +// ignore_for_file: always_put_required_named_parameters_first +// ignore_for_file: constant_identifier_names +// ignore_for_file: lines_longer_than_80_chars + +part of openapi.api; + +class FilesystemListingItemDto { + /// Returns a new [FilesystemListingItemDto] instance. + FilesystemListingItemDto({ + required this.isDirectory, + required this.path, + }); + + bool isDirectory; + + String path; + + @override + bool operator ==(Object other) => identical(this, other) || other is FilesystemListingItemDto && + other.isDirectory == isDirectory && + other.path == path; + + @override + int get hashCode => + // ignore: unnecessary_parenthesis + (isDirectory.hashCode) + + (path.hashCode); + + @override + String toString() => 'FilesystemListingItemDto[isDirectory=$isDirectory, path=$path]'; + + Map toJson() { + final json = {}; + json[r'isDirectory'] = this.isDirectory; + json[r'path'] = this.path; + return json; + } + + /// Returns a new [FilesystemListingItemDto] instance and imports its values from + /// [value] if it's a [Map], null otherwise. + // ignore: prefer_constructors_over_static_methods + static FilesystemListingItemDto? fromJson(dynamic value) { + upgradeDto(value, "FilesystemListingItemDto"); + if (value is Map) { + final json = value.cast(); + + return FilesystemListingItemDto( + isDirectory: mapValueOfType(json, r'isDirectory')!, + path: mapValueOfType(json, r'path')!, + ); + } + 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 = FilesystemListingItemDto.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 = FilesystemListingItemDto.fromJson(entry.value); + if (value != null) { + map[entry.key] = value; + } + } + } + return map; + } + + // maps a json object with a list of FilesystemListingItemDto-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] = FilesystemListingItemDto.listFromJson(entry.value, growable: growable,); + } + } + return map; + } + + /// The list of required keys that must be present in a JSON. + static const requiredKeys = { + 'isDirectory', + 'path', + }; +} + diff --git a/mobile/openapi/lib/model/filesystem_listing_response_dto.dart b/mobile/openapi/lib/model/filesystem_listing_response_dto.dart new file mode 100644 index 0000000000..16c90d1070 --- /dev/null +++ b/mobile/openapi/lib/model/filesystem_listing_response_dto.dart @@ -0,0 +1,115 @@ +// +// AUTO-GENERATED FILE, DO NOT MODIFY! +// +// @dart=2.18 + +// ignore_for_file: unused_element, unused_import +// ignore_for_file: always_put_required_named_parameters_first +// ignore_for_file: constant_identifier_names +// ignore_for_file: lines_longer_than_80_chars + +part of openapi.api; + +class FilesystemListingResponseDto { + /// Returns a new [FilesystemListingResponseDto] instance. + FilesystemListingResponseDto({ + this.items = const [], + required this.parent, + required this.path, + }); + + List items; + + String parent; + + String path; + + @override + bool operator ==(Object other) => identical(this, other) || other is FilesystemListingResponseDto && + _deepEquality.equals(other.items, items) && + other.parent == parent && + other.path == path; + + @override + int get hashCode => + // ignore: unnecessary_parenthesis + (items.hashCode) + + (parent.hashCode) + + (path.hashCode); + + @override + String toString() => 'FilesystemListingResponseDto[items=$items, parent=$parent, path=$path]'; + + Map toJson() { + final json = {}; + json[r'items'] = this.items; + json[r'parent'] = this.parent; + json[r'path'] = this.path; + return json; + } + + /// Returns a new [FilesystemListingResponseDto] instance and imports its values from + /// [value] if it's a [Map], null otherwise. + // ignore: prefer_constructors_over_static_methods + static FilesystemListingResponseDto? fromJson(dynamic value) { + upgradeDto(value, "FilesystemListingResponseDto"); + if (value is Map) { + final json = value.cast(); + + return FilesystemListingResponseDto( + items: FilesystemListingItemDto.listFromJson(json[r'items']), + parent: mapValueOfType(json, r'parent')!, + path: mapValueOfType(json, r'path')!, + ); + } + 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 = FilesystemListingResponseDto.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 = FilesystemListingResponseDto.fromJson(entry.value); + if (value != null) { + map[entry.key] = value; + } + } + } + return map; + } + + // maps a json object with a list of FilesystemListingResponseDto-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] = FilesystemListingResponseDto.listFromJson(entry.value, growable: growable,); + } + } + return map; + } + + /// The list of required keys that must be present in a JSON. + static const requiredKeys = { + 'items', + 'parent', + 'path', + }; +} + diff --git a/mobile/openapi/lib/model/immich_integration_configuration_dto.dart b/mobile/openapi/lib/model/immich_integration_configuration_dto.dart new file mode 100644 index 0000000000..1605117b10 --- /dev/null +++ b/mobile/openapi/lib/model/immich_integration_configuration_dto.dart @@ -0,0 +1,117 @@ +// +// AUTO-GENERATED FILE, DO NOT MODIFY! +// +// @dart=2.18 + +// ignore_for_file: unused_element, unused_import +// ignore_for_file: always_put_required_named_parameters_first +// ignore_for_file: constant_identifier_names +// ignore_for_file: lines_longer_than_80_chars + +part of openapi.api; + +class ImmichIntegrationConfigurationDto { + /// Returns a new [ImmichIntegrationConfigurationDto] instance. + ImmichIntegrationConfigurationDto({ + required this.backupConfiguration, + this.dataFolders = const [], + required this.libraries, + }); + + bool backupConfiguration; + + List dataFolders; + + ConfigureImmichIntegrationRequestDtoLibraries libraries; + + @override + bool operator ==(Object other) => identical(this, other) || other is ImmichIntegrationConfigurationDto && + other.backupConfiguration == backupConfiguration && + _deepEquality.equals(other.dataFolders, dataFolders) && + other.libraries == libraries; + + @override + int get hashCode => + // ignore: unnecessary_parenthesis + (backupConfiguration.hashCode) + + (dataFolders.hashCode) + + (libraries.hashCode); + + @override + String toString() => 'ImmichIntegrationConfigurationDto[backupConfiguration=$backupConfiguration, dataFolders=$dataFolders, libraries=$libraries]'; + + Map toJson() { + final json = {}; + json[r'backupConfiguration'] = this.backupConfiguration; + json[r'dataFolders'] = this.dataFolders; + json[r'libraries'] = this.libraries; + return json; + } + + /// Returns a new [ImmichIntegrationConfigurationDto] instance and imports its values from + /// [value] if it's a [Map], null otherwise. + // ignore: prefer_constructors_over_static_methods + static ImmichIntegrationConfigurationDto? fromJson(dynamic value) { + upgradeDto(value, "ImmichIntegrationConfigurationDto"); + if (value is Map) { + final json = value.cast(); + + return ImmichIntegrationConfigurationDto( + backupConfiguration: mapValueOfType(json, r'backupConfiguration')!, + dataFolders: json[r'dataFolders'] is Iterable + ? (json[r'dataFolders'] as Iterable).cast().toList(growable: false) + : const [], + libraries: ConfigureImmichIntegrationRequestDtoLibraries.fromJson(json[r'libraries'])!, + ); + } + 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 = ImmichIntegrationConfigurationDto.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 = ImmichIntegrationConfigurationDto.fromJson(entry.value); + if (value != null) { + map[entry.key] = value; + } + } + } + return map; + } + + // maps a json object with a list of ImmichIntegrationConfigurationDto-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] = ImmichIntegrationConfigurationDto.listFromJson(entry.value, growable: growable,); + } + } + return map; + } + + /// The list of required keys that must be present in a JSON. + static const requiredKeys = { + 'backupConfiguration', + 'dataFolders', + 'libraries', + }; +} + diff --git a/mobile/openapi/lib/model/immich_integration_dto.dart b/mobile/openapi/lib/model/immich_integration_dto.dart new file mode 100644 index 0000000000..920b39fe7e --- /dev/null +++ b/mobile/openapi/lib/model/immich_integration_dto.dart @@ -0,0 +1,115 @@ +// +// AUTO-GENERATED FILE, DO NOT MODIFY! +// +// @dart=2.18 + +// ignore_for_file: unused_element, unused_import +// ignore_for_file: always_put_required_named_parameters_first +// ignore_for_file: constant_identifier_names +// ignore_for_file: lines_longer_than_80_chars + +part of openapi.api; + +class ImmichIntegrationDto { + /// Returns a new [ImmichIntegrationDto] instance. + ImmichIntegrationDto({ + required this.configuration, + required this.id, + required this.scheduleId, + }); + + ImmichIntegrationConfigurationDto configuration; + + String id; + + String scheduleId; + + @override + bool operator ==(Object other) => identical(this, other) || other is ImmichIntegrationDto && + other.configuration == configuration && + other.id == id && + other.scheduleId == scheduleId; + + @override + int get hashCode => + // ignore: unnecessary_parenthesis + (configuration.hashCode) + + (id.hashCode) + + (scheduleId.hashCode); + + @override + String toString() => 'ImmichIntegrationDto[configuration=$configuration, id=$id, scheduleId=$scheduleId]'; + + Map toJson() { + final json = {}; + json[r'configuration'] = this.configuration; + json[r'id'] = this.id; + json[r'scheduleId'] = this.scheduleId; + return json; + } + + /// Returns a new [ImmichIntegrationDto] instance and imports its values from + /// [value] if it's a [Map], null otherwise. + // ignore: prefer_constructors_over_static_methods + static ImmichIntegrationDto? fromJson(dynamic value) { + upgradeDto(value, "ImmichIntegrationDto"); + if (value is Map) { + final json = value.cast(); + + return ImmichIntegrationDto( + configuration: ImmichIntegrationConfigurationDto.fromJson(json[r'configuration'])!, + id: mapValueOfType(json, r'id')!, + scheduleId: mapValueOfType(json, r'scheduleId')!, + ); + } + 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 = ImmichIntegrationDto.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 = ImmichIntegrationDto.fromJson(entry.value); + if (value != null) { + map[entry.key] = value; + } + } + } + return map; + } + + // maps a json object with a list of ImmichIntegrationDto-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] = ImmichIntegrationDto.listFromJson(entry.value, growable: growable,); + } + } + return map; + } + + /// The list of required keys that must be present in a JSON. + static const requiredKeys = { + 'configuration', + 'id', + 'scheduleId', + }; +} + diff --git a/mobile/openapi/lib/model/immich_library_dto.dart b/mobile/openapi/lib/model/immich_library_dto.dart new file mode 100644 index 0000000000..0a812885fa --- /dev/null +++ b/mobile/openapi/lib/model/immich_library_dto.dart @@ -0,0 +1,127 @@ +// +// AUTO-GENERATED FILE, DO NOT MODIFY! +// +// @dart=2.18 + +// ignore_for_file: unused_element, unused_import +// ignore_for_file: always_put_required_named_parameters_first +// ignore_for_file: constant_identifier_names +// ignore_for_file: lines_longer_than_80_chars + +part of openapi.api; + +class ImmichLibraryDto { + /// Returns a new [ImmichLibraryDto] instance. + ImmichLibraryDto({ + this.exclusionPatterns = const [], + required this.id, + this.importPaths = const [], + required this.name, + }); + + List exclusionPatterns; + + String id; + + List importPaths; + + String name; + + @override + bool operator ==(Object other) => identical(this, other) || other is ImmichLibraryDto && + _deepEquality.equals(other.exclusionPatterns, exclusionPatterns) && + other.id == id && + _deepEquality.equals(other.importPaths, importPaths) && + other.name == name; + + @override + int get hashCode => + // ignore: unnecessary_parenthesis + (exclusionPatterns.hashCode) + + (id.hashCode) + + (importPaths.hashCode) + + (name.hashCode); + + @override + String toString() => 'ImmichLibraryDto[exclusionPatterns=$exclusionPatterns, id=$id, importPaths=$importPaths, name=$name]'; + + Map toJson() { + final json = {}; + json[r'exclusionPatterns'] = this.exclusionPatterns; + json[r'id'] = this.id; + json[r'importPaths'] = this.importPaths; + json[r'name'] = this.name; + return json; + } + + /// Returns a new [ImmichLibraryDto] instance and imports its values from + /// [value] if it's a [Map], null otherwise. + // ignore: prefer_constructors_over_static_methods + static ImmichLibraryDto? fromJson(dynamic value) { + upgradeDto(value, "ImmichLibraryDto"); + if (value is Map) { + final json = value.cast(); + + return ImmichLibraryDto( + exclusionPatterns: json[r'exclusionPatterns'] is Iterable + ? (json[r'exclusionPatterns'] as Iterable).cast().toList(growable: false) + : const [], + id: mapValueOfType(json, r'id')!, + importPaths: json[r'importPaths'] is Iterable + ? (json[r'importPaths'] as Iterable).cast().toList(growable: false) + : const [], + name: mapValueOfType(json, r'name')!, + ); + } + 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 = ImmichLibraryDto.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 = ImmichLibraryDto.fromJson(entry.value); + if (value != null) { + map[entry.key] = value; + } + } + } + return map; + } + + // maps a json object with a list of ImmichLibraryDto-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] = ImmichLibraryDto.listFromJson(entry.value, growable: growable,); + } + } + return map; + } + + /// The list of required keys that must be present in a JSON. + static const requiredKeys = { + 'exclusionPatterns', + 'id', + 'importPaths', + 'name', + }; +} + diff --git a/mobile/openapi/lib/model/immich_state_dto.dart b/mobile/openapi/lib/model/immich_state_dto.dart new file mode 100644 index 0000000000..0314cbfa72 --- /dev/null +++ b/mobile/openapi/lib/model/immich_state_dto.dart @@ -0,0 +1,117 @@ +// +// AUTO-GENERATED FILE, DO NOT MODIFY! +// +// @dart=2.18 + +// ignore_for_file: unused_element, unused_import +// ignore_for_file: always_put_required_named_parameters_first +// ignore_for_file: constant_identifier_names +// ignore_for_file: lines_longer_than_80_chars + +part of openapi.api; + +class ImmichStateDto { + /// Returns a new [ImmichStateDto] instance. + ImmichStateDto({ + this.dataFolders = const [], + required this.dataPath, + this.libraries = const [], + }); + + List dataFolders; + + String dataPath; + + List libraries; + + @override + bool operator ==(Object other) => identical(this, other) || other is ImmichStateDto && + _deepEquality.equals(other.dataFolders, dataFolders) && + other.dataPath == dataPath && + _deepEquality.equals(other.libraries, libraries); + + @override + int get hashCode => + // ignore: unnecessary_parenthesis + (dataFolders.hashCode) + + (dataPath.hashCode) + + (libraries.hashCode); + + @override + String toString() => 'ImmichStateDto[dataFolders=$dataFolders, dataPath=$dataPath, libraries=$libraries]'; + + Map toJson() { + final json = {}; + json[r'dataFolders'] = this.dataFolders; + json[r'dataPath'] = this.dataPath; + json[r'libraries'] = this.libraries; + return json; + } + + /// Returns a new [ImmichStateDto] instance and imports its values from + /// [value] if it's a [Map], null otherwise. + // ignore: prefer_constructors_over_static_methods + static ImmichStateDto? fromJson(dynamic value) { + upgradeDto(value, "ImmichStateDto"); + if (value is Map) { + final json = value.cast(); + + return ImmichStateDto( + dataFolders: json[r'dataFolders'] is Iterable + ? (json[r'dataFolders'] as Iterable).cast().toList(growable: false) + : const [], + dataPath: mapValueOfType(json, r'dataPath')!, + libraries: ImmichLibraryDto.listFromJson(json[r'libraries']), + ); + } + 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 = ImmichStateDto.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 = ImmichStateDto.fromJson(entry.value); + if (value != null) { + map[entry.key] = value; + } + } + } + return map; + } + + // maps a json object with a list of ImmichStateDto-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] = ImmichStateDto.listFromJson(entry.value, growable: growable,); + } + } + return map; + } + + /// The list of required keys that must be present in a JSON. + static const requiredKeys = { + 'dataFolders', + 'dataPath', + 'libraries', + }; +} + diff --git a/mobile/openapi/lib/model/import_recovery_key_request.dart b/mobile/openapi/lib/model/import_recovery_key_request.dart new file mode 100644 index 0000000000..ec91d2b8e0 --- /dev/null +++ b/mobile/openapi/lib/model/import_recovery_key_request.dart @@ -0,0 +1,99 @@ +// +// AUTO-GENERATED FILE, DO NOT MODIFY! +// +// @dart=2.18 + +// ignore_for_file: unused_element, unused_import +// ignore_for_file: always_put_required_named_parameters_first +// ignore_for_file: constant_identifier_names +// ignore_for_file: lines_longer_than_80_chars + +part of openapi.api; + +class ImportRecoveryKeyRequest { + /// Returns a new [ImportRecoveryKeyRequest] instance. + ImportRecoveryKeyRequest({ + required this.recoveryKey, + }); + + String recoveryKey; + + @override + bool operator ==(Object other) => identical(this, other) || other is ImportRecoveryKeyRequest && + other.recoveryKey == recoveryKey; + + @override + int get hashCode => + // ignore: unnecessary_parenthesis + (recoveryKey.hashCode); + + @override + String toString() => 'ImportRecoveryKeyRequest[recoveryKey=$recoveryKey]'; + + Map toJson() { + final json = {}; + json[r'recoveryKey'] = this.recoveryKey; + return json; + } + + /// Returns a new [ImportRecoveryKeyRequest] instance and imports its values from + /// [value] if it's a [Map], null otherwise. + // ignore: prefer_constructors_over_static_methods + static ImportRecoveryKeyRequest? fromJson(dynamic value) { + upgradeDto(value, "ImportRecoveryKeyRequest"); + if (value is Map) { + final json = value.cast(); + + return ImportRecoveryKeyRequest( + recoveryKey: mapValueOfType(json, r'recoveryKey')!, + ); + } + 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 = ImportRecoveryKeyRequest.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 = ImportRecoveryKeyRequest.fromJson(entry.value); + if (value != null) { + map[entry.key] = value; + } + } + } + return map; + } + + // maps a json object with a list of ImportRecoveryKeyRequest-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] = ImportRecoveryKeyRequest.listFromJson(entry.value, growable: growable,); + } + } + return map; + } + + /// The list of required keys that must be present in a JSON. + static const requiredKeys = { + 'recoveryKey', + }; +} + diff --git a/mobile/openapi/lib/model/inspected_local_repository_dto.dart b/mobile/openapi/lib/model/inspected_local_repository_dto.dart new file mode 100644 index 0000000000..e832962898 --- /dev/null +++ b/mobile/openapi/lib/model/inspected_local_repository_dto.dart @@ -0,0 +1,165 @@ +// +// AUTO-GENERATED FILE, DO NOT MODIFY! +// +// @dart=2.18 + +// ignore_for_file: unused_element, unused_import +// ignore_for_file: always_put_required_named_parameters_first +// ignore_for_file: constant_identifier_names +// ignore_for_file: lines_longer_than_80_chars + +part of openapi.api; + +class InspectedLocalRepositoryDto { + /// Returns a new [InspectedLocalRepositoryDto] instance. + InspectedLocalRepositoryDto({ + this.backends, + this.configuration, + required this.id, + required this.metrics, + required this.name, + this.snapshots = const [], + required this.worm, + }); + + /// + /// 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. + /// + RepositoryBackendsDto? backends; + + /// + /// 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. + /// + RepositoryConfigurationDto? configuration; + + String id; + + RepositoryMetricsDto metrics; + + String name; + + List snapshots; + + bool worm; + + @override + bool operator ==(Object other) => identical(this, other) || other is InspectedLocalRepositoryDto && + other.backends == backends && + other.configuration == configuration && + other.id == id && + other.metrics == metrics && + other.name == name && + _deepEquality.equals(other.snapshots, snapshots) && + other.worm == worm; + + @override + int get hashCode => + // ignore: unnecessary_parenthesis + (backends == null ? 0 : backends!.hashCode) + + (configuration == null ? 0 : configuration!.hashCode) + + (id.hashCode) + + (metrics.hashCode) + + (name.hashCode) + + (snapshots.hashCode) + + (worm.hashCode); + + @override + String toString() => 'InspectedLocalRepositoryDto[backends=$backends, configuration=$configuration, id=$id, metrics=$metrics, name=$name, snapshots=$snapshots, worm=$worm]'; + + Map toJson() { + final json = {}; + if (this.backends != null) { + json[r'backends'] = this.backends; + } else { + // json[r'backends'] = null; + } + if (this.configuration != null) { + json[r'configuration'] = this.configuration; + } else { + // json[r'configuration'] = null; + } + json[r'id'] = this.id; + json[r'metrics'] = this.metrics; + json[r'name'] = this.name; + json[r'snapshots'] = this.snapshots; + json[r'worm'] = this.worm; + return json; + } + + /// Returns a new [InspectedLocalRepositoryDto] instance and imports its values from + /// [value] if it's a [Map], null otherwise. + // ignore: prefer_constructors_over_static_methods + static InspectedLocalRepositoryDto? fromJson(dynamic value) { + upgradeDto(value, "InspectedLocalRepositoryDto"); + if (value is Map) { + final json = value.cast(); + + return InspectedLocalRepositoryDto( + backends: RepositoryBackendsDto.fromJson(json[r'backends']), + configuration: RepositoryConfigurationDto.fromJson(json[r'configuration']), + id: mapValueOfType(json, r'id')!, + metrics: RepositoryMetricsDto.fromJson(json[r'metrics'])!, + name: mapValueOfType(json, r'name')!, + snapshots: SnapshotDto.listFromJson(json[r'snapshots']), + worm: mapValueOfType(json, r'worm')!, + ); + } + 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 = InspectedLocalRepositoryDto.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 = InspectedLocalRepositoryDto.fromJson(entry.value); + if (value != null) { + map[entry.key] = value; + } + } + } + return map; + } + + // maps a json object with a list of InspectedLocalRepositoryDto-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] = InspectedLocalRepositoryDto.listFromJson(entry.value, growable: growable,); + } + } + return map; + } + + /// The list of required keys that must be present in a JSON. + static const requiredKeys = { + 'id', + 'metrics', + 'name', + 'snapshots', + 'worm', + }; +} + diff --git a/mobile/openapi/lib/model/integrations_response_dto.dart b/mobile/openapi/lib/model/integrations_response_dto.dart new file mode 100644 index 0000000000..4b37dd8b84 --- /dev/null +++ b/mobile/openapi/lib/model/integrations_response_dto.dart @@ -0,0 +1,125 @@ +// +// AUTO-GENERATED FILE, DO NOT MODIFY! +// +// @dart=2.18 + +// ignore_for_file: unused_element, unused_import +// ignore_for_file: always_put_required_named_parameters_first +// ignore_for_file: constant_identifier_names +// ignore_for_file: lines_longer_than_80_chars + +part of openapi.api; + +class IntegrationsResponseDto { + /// Returns a new [IntegrationsResponseDto] instance. + IntegrationsResponseDto({ + this.immichIntegration, + this.immichState, + }); + + /// + /// 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. + /// + ImmichIntegrationDto? immichIntegration; + + /// + /// 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. + /// + ImmichStateDto? immichState; + + @override + bool operator ==(Object other) => identical(this, other) || other is IntegrationsResponseDto && + other.immichIntegration == immichIntegration && + other.immichState == immichState; + + @override + int get hashCode => + // ignore: unnecessary_parenthesis + (immichIntegration == null ? 0 : immichIntegration!.hashCode) + + (immichState == null ? 0 : immichState!.hashCode); + + @override + String toString() => 'IntegrationsResponseDto[immichIntegration=$immichIntegration, immichState=$immichState]'; + + Map toJson() { + final json = {}; + if (this.immichIntegration != null) { + json[r'immichIntegration'] = this.immichIntegration; + } else { + // json[r'immichIntegration'] = null; + } + if (this.immichState != null) { + json[r'immichState'] = this.immichState; + } else { + // json[r'immichState'] = null; + } + return json; + } + + /// Returns a new [IntegrationsResponseDto] instance and imports its values from + /// [value] if it's a [Map], null otherwise. + // ignore: prefer_constructors_over_static_methods + static IntegrationsResponseDto? fromJson(dynamic value) { + upgradeDto(value, "IntegrationsResponseDto"); + if (value is Map) { + final json = value.cast(); + + return IntegrationsResponseDto( + immichIntegration: ImmichIntegrationDto.fromJson(json[r'immichIntegration']), + immichState: ImmichStateDto.fromJson(json[r'immichState']), + ); + } + 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 = IntegrationsResponseDto.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 = IntegrationsResponseDto.fromJson(entry.value); + if (value != null) { + map[entry.key] = value; + } + } + } + return map; + } + + // maps a json object with a list of IntegrationsResponseDto-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] = IntegrationsResponseDto.listFromJson(entry.value, growable: growable,); + } + } + return map; + } + + /// The list of required keys that must be present in a JSON. + static const requiredKeys = { + }; +} + diff --git a/mobile/openapi/lib/model/list_snapshots_response_dto.dart b/mobile/openapi/lib/model/list_snapshots_response_dto.dart new file mode 100644 index 0000000000..2136c80d5c --- /dev/null +++ b/mobile/openapi/lib/model/list_snapshots_response_dto.dart @@ -0,0 +1,99 @@ +// +// AUTO-GENERATED FILE, DO NOT MODIFY! +// +// @dart=2.18 + +// ignore_for_file: unused_element, unused_import +// ignore_for_file: always_put_required_named_parameters_first +// ignore_for_file: constant_identifier_names +// ignore_for_file: lines_longer_than_80_chars + +part of openapi.api; + +class ListSnapshotsResponseDto { + /// Returns a new [ListSnapshotsResponseDto] instance. + ListSnapshotsResponseDto({ + this.snapshots = const [], + }); + + List snapshots; + + @override + bool operator ==(Object other) => identical(this, other) || other is ListSnapshotsResponseDto && + _deepEquality.equals(other.snapshots, snapshots); + + @override + int get hashCode => + // ignore: unnecessary_parenthesis + (snapshots.hashCode); + + @override + String toString() => 'ListSnapshotsResponseDto[snapshots=$snapshots]'; + + Map toJson() { + final json = {}; + json[r'snapshots'] = this.snapshots; + return json; + } + + /// Returns a new [ListSnapshotsResponseDto] instance and imports its values from + /// [value] if it's a [Map], null otherwise. + // ignore: prefer_constructors_over_static_methods + static ListSnapshotsResponseDto? fromJson(dynamic value) { + upgradeDto(value, "ListSnapshotsResponseDto"); + if (value is Map) { + final json = value.cast(); + + return ListSnapshotsResponseDto( + snapshots: SnapshotDto.listFromJson(json[r'snapshots']), + ); + } + 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 = ListSnapshotsResponseDto.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 = ListSnapshotsResponseDto.fromJson(entry.value); + if (value != null) { + map[entry.key] = value; + } + } + } + return map; + } + + // maps a json object with a list of ListSnapshotsResponseDto-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] = ListSnapshotsResponseDto.listFromJson(entry.value, growable: growable,); + } + } + return map; + } + + /// The list of required keys that must be present in a JSON. + static const requiredKeys = { + 'snapshots', + }; +} + diff --git a/mobile/openapi/lib/model/local_repository_dto.dart b/mobile/openapi/lib/model/local_repository_dto.dart new file mode 100644 index 0000000000..92b5555bf8 --- /dev/null +++ b/mobile/openapi/lib/model/local_repository_dto.dart @@ -0,0 +1,157 @@ +// +// AUTO-GENERATED FILE, DO NOT MODIFY! +// +// @dart=2.18 + +// ignore_for_file: unused_element, unused_import +// ignore_for_file: always_put_required_named_parameters_first +// ignore_for_file: constant_identifier_names +// ignore_for_file: lines_longer_than_80_chars + +part of openapi.api; + +class LocalRepositoryDto { + /// Returns a new [LocalRepositoryDto] instance. + LocalRepositoryDto({ + this.backends, + this.configuration, + required this.id, + required this.metrics, + required this.name, + required this.worm, + }); + + /// + /// 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. + /// + RepositoryBackendsDto? backends; + + /// + /// 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. + /// + RepositoryConfigurationDto? configuration; + + String id; + + RepositoryMetricsDto metrics; + + String name; + + bool worm; + + @override + bool operator ==(Object other) => identical(this, other) || other is LocalRepositoryDto && + other.backends == backends && + other.configuration == configuration && + other.id == id && + other.metrics == metrics && + other.name == name && + other.worm == worm; + + @override + int get hashCode => + // ignore: unnecessary_parenthesis + (backends == null ? 0 : backends!.hashCode) + + (configuration == null ? 0 : configuration!.hashCode) + + (id.hashCode) + + (metrics.hashCode) + + (name.hashCode) + + (worm.hashCode); + + @override + String toString() => 'LocalRepositoryDto[backends=$backends, configuration=$configuration, id=$id, metrics=$metrics, name=$name, worm=$worm]'; + + Map toJson() { + final json = {}; + if (this.backends != null) { + json[r'backends'] = this.backends; + } else { + // json[r'backends'] = null; + } + if (this.configuration != null) { + json[r'configuration'] = this.configuration; + } else { + // json[r'configuration'] = null; + } + json[r'id'] = this.id; + json[r'metrics'] = this.metrics; + json[r'name'] = this.name; + json[r'worm'] = this.worm; + return json; + } + + /// Returns a new [LocalRepositoryDto] instance and imports its values from + /// [value] if it's a [Map], null otherwise. + // ignore: prefer_constructors_over_static_methods + static LocalRepositoryDto? fromJson(dynamic value) { + upgradeDto(value, "LocalRepositoryDto"); + if (value is Map) { + final json = value.cast(); + + return LocalRepositoryDto( + backends: RepositoryBackendsDto.fromJson(json[r'backends']), + configuration: RepositoryConfigurationDto.fromJson(json[r'configuration']), + id: mapValueOfType(json, r'id')!, + metrics: RepositoryMetricsDto.fromJson(json[r'metrics'])!, + name: mapValueOfType(json, r'name')!, + worm: mapValueOfType(json, r'worm')!, + ); + } + 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 = LocalRepositoryDto.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 = LocalRepositoryDto.fromJson(entry.value); + if (value != null) { + map[entry.key] = value; + } + } + } + return map; + } + + // maps a json object with a list of LocalRepositoryDto-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] = LocalRepositoryDto.listFromJson(entry.value, growable: growable,); + } + } + return map; + } + + /// The list of required keys that must be present in a JSON. + static const requiredKeys = { + 'id', + 'metrics', + 'name', + 'worm', + }; +} + diff --git a/mobile/openapi/lib/model/log_response_dto.dart b/mobile/openapi/lib/model/log_response_dto.dart new file mode 100644 index 0000000000..7caf1efb5e --- /dev/null +++ b/mobile/openapi/lib/model/log_response_dto.dart @@ -0,0 +1,99 @@ +// +// AUTO-GENERATED FILE, DO NOT MODIFY! +// +// @dart=2.18 + +// ignore_for_file: unused_element, unused_import +// ignore_for_file: always_put_required_named_parameters_first +// ignore_for_file: constant_identifier_names +// ignore_for_file: lines_longer_than_80_chars + +part of openapi.api; + +class LogResponseDto { + /// Returns a new [LogResponseDto] instance. + LogResponseDto({ + required this.logId, + }); + + String logId; + + @override + bool operator ==(Object other) => identical(this, other) || other is LogResponseDto && + other.logId == logId; + + @override + int get hashCode => + // ignore: unnecessary_parenthesis + (logId.hashCode); + + @override + String toString() => 'LogResponseDto[logId=$logId]'; + + Map toJson() { + final json = {}; + json[r'logId'] = this.logId; + return json; + } + + /// Returns a new [LogResponseDto] instance and imports its values from + /// [value] if it's a [Map], null otherwise. + // ignore: prefer_constructors_over_static_methods + static LogResponseDto? fromJson(dynamic value) { + upgradeDto(value, "LogResponseDto"); + if (value is Map) { + final json = value.cast(); + + return LogResponseDto( + logId: mapValueOfType(json, r'logId')!, + ); + } + 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 = LogResponseDto.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 = LogResponseDto.fromJson(entry.value); + if (value != null) { + map[entry.key] = value; + } + } + } + return map; + } + + // maps a json object with a list of LogResponseDto-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] = LogResponseDto.listFromJson(entry.value, growable: growable,); + } + } + return map; + } + + /// The list of required keys that must be present in a JSON. + static const requiredKeys = { + 'logId', + }; +} + diff --git a/mobile/openapi/lib/model/onboarding_status_response_dto.dart b/mobile/openapi/lib/model/onboarding_status_response_dto.dart new file mode 100644 index 0000000000..8249e015b6 --- /dev/null +++ b/mobile/openapi/lib/model/onboarding_status_response_dto.dart @@ -0,0 +1,131 @@ +// +// AUTO-GENERATED FILE, DO NOT MODIFY! +// +// @dart=2.18 + +// ignore_for_file: unused_element, unused_import +// ignore_for_file: always_put_required_named_parameters_first +// ignore_for_file: constant_identifier_names +// ignore_for_file: lines_longer_than_80_chars + +part of openapi.api; + +class OnboardingStatusResponseDto { + /// Returns a new [OnboardingStatusResponseDto] instance. + OnboardingStatusResponseDto({ + required this.hasBackend, + required this.hasBackup, + required this.hasOnboardedKey, + required this.hasSchedule, + required this.hasSkippedExtraConfig, + }); + + bool hasBackend; + + bool hasBackup; + + bool hasOnboardedKey; + + bool hasSchedule; + + bool hasSkippedExtraConfig; + + @override + bool operator ==(Object other) => identical(this, other) || other is OnboardingStatusResponseDto && + other.hasBackend == hasBackend && + other.hasBackup == hasBackup && + other.hasOnboardedKey == hasOnboardedKey && + other.hasSchedule == hasSchedule && + other.hasSkippedExtraConfig == hasSkippedExtraConfig; + + @override + int get hashCode => + // ignore: unnecessary_parenthesis + (hasBackend.hashCode) + + (hasBackup.hashCode) + + (hasOnboardedKey.hashCode) + + (hasSchedule.hashCode) + + (hasSkippedExtraConfig.hashCode); + + @override + String toString() => 'OnboardingStatusResponseDto[hasBackend=$hasBackend, hasBackup=$hasBackup, hasOnboardedKey=$hasOnboardedKey, hasSchedule=$hasSchedule, hasSkippedExtraConfig=$hasSkippedExtraConfig]'; + + Map toJson() { + final json = {}; + json[r'hasBackend'] = this.hasBackend; + json[r'hasBackup'] = this.hasBackup; + json[r'hasOnboardedKey'] = this.hasOnboardedKey; + json[r'hasSchedule'] = this.hasSchedule; + json[r'hasSkippedExtraConfig'] = this.hasSkippedExtraConfig; + return json; + } + + /// Returns a new [OnboardingStatusResponseDto] instance and imports its values from + /// [value] if it's a [Map], null otherwise. + // ignore: prefer_constructors_over_static_methods + static OnboardingStatusResponseDto? fromJson(dynamic value) { + upgradeDto(value, "OnboardingStatusResponseDto"); + if (value is Map) { + final json = value.cast(); + + return OnboardingStatusResponseDto( + hasBackend: mapValueOfType(json, r'hasBackend')!, + hasBackup: mapValueOfType(json, r'hasBackup')!, + hasOnboardedKey: mapValueOfType(json, r'hasOnboardedKey')!, + hasSchedule: mapValueOfType(json, r'hasSchedule')!, + hasSkippedExtraConfig: mapValueOfType(json, r'hasSkippedExtraConfig')!, + ); + } + 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 = OnboardingStatusResponseDto.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 = OnboardingStatusResponseDto.fromJson(entry.value); + if (value != null) { + map[entry.key] = value; + } + } + } + return map; + } + + // maps a json object with a list of OnboardingStatusResponseDto-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] = OnboardingStatusResponseDto.listFromJson(entry.value, growable: growable,); + } + } + return map; + } + + /// The list of required keys that must be present in a JSON. + static const requiredKeys = { + 'hasBackend', + 'hasBackup', + 'hasOnboardedKey', + 'hasSchedule', + 'hasSkippedExtraConfig', + }; +} + diff --git a/mobile/openapi/lib/model/repository_backend_dto.dart b/mobile/openapi/lib/model/repository_backend_dto.dart new file mode 100644 index 0000000000..b955832c48 --- /dev/null +++ b/mobile/openapi/lib/model/repository_backend_dto.dart @@ -0,0 +1,115 @@ +// +// AUTO-GENERATED FILE, DO NOT MODIFY! +// +// @dart=2.18 + +// ignore_for_file: unused_element, unused_import +// ignore_for_file: always_put_required_named_parameters_first +// ignore_for_file: constant_identifier_names +// ignore_for_file: lines_longer_than_80_chars + +part of openapi.api; + +class RepositoryBackendDto { + /// Returns a new [RepositoryBackendDto] instance. + RepositoryBackendDto({ + required this.id, + required this.online, + required this.type, + }); + + String id; + + bool online; + + BackendType type; + + @override + bool operator ==(Object other) => identical(this, other) || other is RepositoryBackendDto && + other.id == id && + other.online == online && + other.type == type; + + @override + int get hashCode => + // ignore: unnecessary_parenthesis + (id.hashCode) + + (online.hashCode) + + (type.hashCode); + + @override + String toString() => 'RepositoryBackendDto[id=$id, online=$online, type=$type]'; + + Map toJson() { + final json = {}; + json[r'id'] = this.id; + json[r'online'] = this.online; + json[r'type'] = this.type; + return json; + } + + /// Returns a new [RepositoryBackendDto] instance and imports its values from + /// [value] if it's a [Map], null otherwise. + // ignore: prefer_constructors_over_static_methods + static RepositoryBackendDto? fromJson(dynamic value) { + upgradeDto(value, "RepositoryBackendDto"); + if (value is Map) { + final json = value.cast(); + + return RepositoryBackendDto( + id: mapValueOfType(json, r'id')!, + online: mapValueOfType(json, r'online')!, + type: BackendType.fromJson(json[r'type'])!, + ); + } + 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 = RepositoryBackendDto.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 = RepositoryBackendDto.fromJson(entry.value); + if (value != null) { + map[entry.key] = value; + } + } + } + return map; + } + + // maps a json object with a list of RepositoryBackendDto-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] = RepositoryBackendDto.listFromJson(entry.value, growable: growable,); + } + } + return map; + } + + /// The list of required keys that must be present in a JSON. + static const requiredKeys = { + 'id', + 'online', + 'type', + }; +} + diff --git a/mobile/openapi/lib/model/repository_backends_dto.dart b/mobile/openapi/lib/model/repository_backends_dto.dart new file mode 100644 index 0000000000..0d74f2e086 --- /dev/null +++ b/mobile/openapi/lib/model/repository_backends_dto.dart @@ -0,0 +1,107 @@ +// +// AUTO-GENERATED FILE, DO NOT MODIFY! +// +// @dart=2.18 + +// ignore_for_file: unused_element, unused_import +// ignore_for_file: always_put_required_named_parameters_first +// ignore_for_file: constant_identifier_names +// ignore_for_file: lines_longer_than_80_chars + +part of openapi.api; + +class RepositoryBackendsDto { + /// Returns a new [RepositoryBackendsDto] instance. + RepositoryBackendsDto({ + required this.primary, + this.secondary = const [], + }); + + RepositoryBackendDto primary; + + List secondary; + + @override + bool operator ==(Object other) => identical(this, other) || other is RepositoryBackendsDto && + other.primary == primary && + _deepEquality.equals(other.secondary, secondary); + + @override + int get hashCode => + // ignore: unnecessary_parenthesis + (primary.hashCode) + + (secondary.hashCode); + + @override + String toString() => 'RepositoryBackendsDto[primary=$primary, secondary=$secondary]'; + + Map toJson() { + final json = {}; + json[r'primary'] = this.primary; + json[r'secondary'] = this.secondary; + return json; + } + + /// Returns a new [RepositoryBackendsDto] instance and imports its values from + /// [value] if it's a [Map], null otherwise. + // ignore: prefer_constructors_over_static_methods + static RepositoryBackendsDto? fromJson(dynamic value) { + upgradeDto(value, "RepositoryBackendsDto"); + if (value is Map) { + final json = value.cast(); + + return RepositoryBackendsDto( + primary: RepositoryBackendDto.fromJson(json[r'primary'])!, + secondary: RepositoryBackendDto.listFromJson(json[r'secondary']), + ); + } + 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 = RepositoryBackendsDto.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 = RepositoryBackendsDto.fromJson(entry.value); + if (value != null) { + map[entry.key] = value; + } + } + } + return map; + } + + // maps a json object with a list of RepositoryBackendsDto-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] = RepositoryBackendsDto.listFromJson(entry.value, growable: growable,); + } + } + return map; + } + + /// The list of required keys that must be present in a JSON. + static const requiredKeys = { + 'primary', + 'secondary', + }; +} + diff --git a/mobile/openapi/lib/model/repository_check_import_response_dto.dart b/mobile/openapi/lib/model/repository_check_import_response_dto.dart new file mode 100644 index 0000000000..fabf882865 --- /dev/null +++ b/mobile/openapi/lib/model/repository_check_import_response_dto.dart @@ -0,0 +1,99 @@ +// +// AUTO-GENERATED FILE, DO NOT MODIFY! +// +// @dart=2.18 + +// ignore_for_file: unused_element, unused_import +// ignore_for_file: always_put_required_named_parameters_first +// ignore_for_file: constant_identifier_names +// ignore_for_file: lines_longer_than_80_chars + +part of openapi.api; + +class RepositoryCheckImportResponseDto { + /// Returns a new [RepositoryCheckImportResponseDto] instance. + RepositoryCheckImportResponseDto({ + required this.readable, + }); + + bool readable; + + @override + bool operator ==(Object other) => identical(this, other) || other is RepositoryCheckImportResponseDto && + other.readable == readable; + + @override + int get hashCode => + // ignore: unnecessary_parenthesis + (readable.hashCode); + + @override + String toString() => 'RepositoryCheckImportResponseDto[readable=$readable]'; + + Map toJson() { + final json = {}; + json[r'readable'] = this.readable; + return json; + } + + /// Returns a new [RepositoryCheckImportResponseDto] instance and imports its values from + /// [value] if it's a [Map], null otherwise. + // ignore: prefer_constructors_over_static_methods + static RepositoryCheckImportResponseDto? fromJson(dynamic value) { + upgradeDto(value, "RepositoryCheckImportResponseDto"); + if (value is Map) { + final json = value.cast(); + + return RepositoryCheckImportResponseDto( + readable: mapValueOfType(json, r'readable')!, + ); + } + 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 = RepositoryCheckImportResponseDto.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 = RepositoryCheckImportResponseDto.fromJson(entry.value); + if (value != null) { + map[entry.key] = value; + } + } + } + return map; + } + + // maps a json object with a list of RepositoryCheckImportResponseDto-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] = RepositoryCheckImportResponseDto.listFromJson(entry.value, growable: growable,); + } + } + return map; + } + + /// The list of required keys that must be present in a JSON. + static const requiredKeys = { + 'readable', + }; +} + diff --git a/mobile/openapi/lib/model/repository_configuration_dto.dart b/mobile/openapi/lib/model/repository_configuration_dto.dart new file mode 100644 index 0000000000..66694e7d56 --- /dev/null +++ b/mobile/openapi/lib/model/repository_configuration_dto.dart @@ -0,0 +1,101 @@ +// +// AUTO-GENERATED FILE, DO NOT MODIFY! +// +// @dart=2.18 + +// ignore_for_file: unused_element, unused_import +// ignore_for_file: always_put_required_named_parameters_first +// ignore_for_file: constant_identifier_names +// ignore_for_file: lines_longer_than_80_chars + +part of openapi.api; + +class RepositoryConfigurationDto { + /// Returns a new [RepositoryConfigurationDto] instance. + RepositoryConfigurationDto({ + this.paths = const [], + }); + + List paths; + + @override + bool operator ==(Object other) => identical(this, other) || other is RepositoryConfigurationDto && + _deepEquality.equals(other.paths, paths); + + @override + int get hashCode => + // ignore: unnecessary_parenthesis + (paths.hashCode); + + @override + String toString() => 'RepositoryConfigurationDto[paths=$paths]'; + + Map toJson() { + final json = {}; + json[r'paths'] = this.paths; + return json; + } + + /// Returns a new [RepositoryConfigurationDto] instance and imports its values from + /// [value] if it's a [Map], null otherwise. + // ignore: prefer_constructors_over_static_methods + static RepositoryConfigurationDto? fromJson(dynamic value) { + upgradeDto(value, "RepositoryConfigurationDto"); + if (value is Map) { + final json = value.cast(); + + return RepositoryConfigurationDto( + paths: json[r'paths'] is Iterable + ? (json[r'paths'] as Iterable).cast().toList(growable: false) + : const [], + ); + } + 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 = RepositoryConfigurationDto.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 = RepositoryConfigurationDto.fromJson(entry.value); + if (value != null) { + map[entry.key] = value; + } + } + } + return map; + } + + // maps a json object with a list of RepositoryConfigurationDto-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] = RepositoryConfigurationDto.listFromJson(entry.value, growable: growable,); + } + } + return map; + } + + /// The list of required keys that must be present in a JSON. + static const requiredKeys = { + 'paths', + }; +} + diff --git a/mobile/openapi/lib/model/repository_create_request_dto.dart b/mobile/openapi/lib/model/repository_create_request_dto.dart new file mode 100644 index 0000000000..708cfcbe8a --- /dev/null +++ b/mobile/openapi/lib/model/repository_create_request_dto.dart @@ -0,0 +1,116 @@ +// +// AUTO-GENERATED FILE, DO NOT MODIFY! +// +// @dart=2.18 + +// ignore_for_file: unused_element, unused_import +// ignore_for_file: always_put_required_named_parameters_first +// ignore_for_file: constant_identifier_names +// ignore_for_file: lines_longer_than_80_chars + +part of openapi.api; + +class RepositoryCreateRequestDto { + /// Returns a new [RepositoryCreateRequestDto] instance. + RepositoryCreateRequestDto({ + required this.name, + this.paths = const [], + required this.worm, + }); + + String name; + + List paths; + + bool worm; + + @override + bool operator ==(Object other) => identical(this, other) || other is RepositoryCreateRequestDto && + other.name == name && + _deepEquality.equals(other.paths, paths) && + other.worm == worm; + + @override + int get hashCode => + // ignore: unnecessary_parenthesis + (name.hashCode) + + (paths.hashCode) + + (worm.hashCode); + + @override + String toString() => 'RepositoryCreateRequestDto[name=$name, paths=$paths, worm=$worm]'; + + Map toJson() { + final json = {}; + json[r'name'] = this.name; + json[r'paths'] = this.paths; + json[r'worm'] = this.worm; + return json; + } + + /// Returns a new [RepositoryCreateRequestDto] instance and imports its values from + /// [value] if it's a [Map], null otherwise. + // ignore: prefer_constructors_over_static_methods + static RepositoryCreateRequestDto? fromJson(dynamic value) { + upgradeDto(value, "RepositoryCreateRequestDto"); + if (value is Map) { + final json = value.cast(); + + return RepositoryCreateRequestDto( + name: mapValueOfType(json, r'name')!, + paths: json[r'paths'] is Iterable + ? (json[r'paths'] as Iterable).cast().toList(growable: false) + : const [], + worm: mapValueOfType(json, r'worm')!, + ); + } + 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 = RepositoryCreateRequestDto.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 = RepositoryCreateRequestDto.fromJson(entry.value); + if (value != null) { + map[entry.key] = value; + } + } + } + return map; + } + + // maps a json object with a list of RepositoryCreateRequestDto-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] = RepositoryCreateRequestDto.listFromJson(entry.value, growable: growable,); + } + } + return map; + } + + /// The list of required keys that must be present in a JSON. + static const requiredKeys = { + 'name', + 'worm', + }; +} + diff --git a/mobile/openapi/lib/model/repository_create_response_dto.dart b/mobile/openapi/lib/model/repository_create_response_dto.dart new file mode 100644 index 0000000000..ab23eff226 --- /dev/null +++ b/mobile/openapi/lib/model/repository_create_response_dto.dart @@ -0,0 +1,99 @@ +// +// AUTO-GENERATED FILE, DO NOT MODIFY! +// +// @dart=2.18 + +// ignore_for_file: unused_element, unused_import +// ignore_for_file: always_put_required_named_parameters_first +// ignore_for_file: constant_identifier_names +// ignore_for_file: lines_longer_than_80_chars + +part of openapi.api; + +class RepositoryCreateResponseDto { + /// Returns a new [RepositoryCreateResponseDto] instance. + RepositoryCreateResponseDto({ + required this.repository, + }); + + LocalRepositoryDto repository; + + @override + bool operator ==(Object other) => identical(this, other) || other is RepositoryCreateResponseDto && + other.repository == repository; + + @override + int get hashCode => + // ignore: unnecessary_parenthesis + (repository.hashCode); + + @override + String toString() => 'RepositoryCreateResponseDto[repository=$repository]'; + + Map toJson() { + final json = {}; + json[r'repository'] = this.repository; + return json; + } + + /// Returns a new [RepositoryCreateResponseDto] instance and imports its values from + /// [value] if it's a [Map], null otherwise. + // ignore: prefer_constructors_over_static_methods + static RepositoryCreateResponseDto? fromJson(dynamic value) { + upgradeDto(value, "RepositoryCreateResponseDto"); + if (value is Map) { + final json = value.cast(); + + return RepositoryCreateResponseDto( + repository: LocalRepositoryDto.fromJson(json[r'repository'])!, + ); + } + 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 = RepositoryCreateResponseDto.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 = RepositoryCreateResponseDto.fromJson(entry.value); + if (value != null) { + map[entry.key] = value; + } + } + } + return map; + } + + // maps a json object with a list of RepositoryCreateResponseDto-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] = RepositoryCreateResponseDto.listFromJson(entry.value, growable: growable,); + } + } + return map; + } + + /// The list of required keys that must be present in a JSON. + static const requiredKeys = { + 'repository', + }; +} + diff --git a/mobile/openapi/lib/model/repository_inspect_response_dto.dart b/mobile/openapi/lib/model/repository_inspect_response_dto.dart new file mode 100644 index 0000000000..75a1820ccc --- /dev/null +++ b/mobile/openapi/lib/model/repository_inspect_response_dto.dart @@ -0,0 +1,99 @@ +// +// AUTO-GENERATED FILE, DO NOT MODIFY! +// +// @dart=2.18 + +// ignore_for_file: unused_element, unused_import +// ignore_for_file: always_put_required_named_parameters_first +// ignore_for_file: constant_identifier_names +// ignore_for_file: lines_longer_than_80_chars + +part of openapi.api; + +class RepositoryInspectResponseDto { + /// Returns a new [RepositoryInspectResponseDto] instance. + RepositoryInspectResponseDto({ + this.repositories = const [], + }); + + List repositories; + + @override + bool operator ==(Object other) => identical(this, other) || other is RepositoryInspectResponseDto && + _deepEquality.equals(other.repositories, repositories); + + @override + int get hashCode => + // ignore: unnecessary_parenthesis + (repositories.hashCode); + + @override + String toString() => 'RepositoryInspectResponseDto[repositories=$repositories]'; + + Map toJson() { + final json = {}; + json[r'repositories'] = this.repositories; + return json; + } + + /// Returns a new [RepositoryInspectResponseDto] instance and imports its values from + /// [value] if it's a [Map], null otherwise. + // ignore: prefer_constructors_over_static_methods + static RepositoryInspectResponseDto? fromJson(dynamic value) { + upgradeDto(value, "RepositoryInspectResponseDto"); + if (value is Map) { + final json = value.cast(); + + return RepositoryInspectResponseDto( + repositories: InspectedLocalRepositoryDto.listFromJson(json[r'repositories']), + ); + } + 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 = RepositoryInspectResponseDto.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 = RepositoryInspectResponseDto.fromJson(entry.value); + if (value != null) { + map[entry.key] = value; + } + } + } + return map; + } + + // maps a json object with a list of RepositoryInspectResponseDto-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] = RepositoryInspectResponseDto.listFromJson(entry.value, growable: growable,); + } + } + return map; + } + + /// The list of required keys that must be present in a JSON. + static const requiredKeys = { + 'repositories', + }; +} + diff --git a/mobile/openapi/lib/model/repository_list_response_dto.dart b/mobile/openapi/lib/model/repository_list_response_dto.dart new file mode 100644 index 0000000000..38ffac509c --- /dev/null +++ b/mobile/openapi/lib/model/repository_list_response_dto.dart @@ -0,0 +1,99 @@ +// +// AUTO-GENERATED FILE, DO NOT MODIFY! +// +// @dart=2.18 + +// ignore_for_file: unused_element, unused_import +// ignore_for_file: always_put_required_named_parameters_first +// ignore_for_file: constant_identifier_names +// ignore_for_file: lines_longer_than_80_chars + +part of openapi.api; + +class RepositoryListResponseDto { + /// Returns a new [RepositoryListResponseDto] instance. + RepositoryListResponseDto({ + this.repositories = const [], + }); + + List repositories; + + @override + bool operator ==(Object other) => identical(this, other) || other is RepositoryListResponseDto && + _deepEquality.equals(other.repositories, repositories); + + @override + int get hashCode => + // ignore: unnecessary_parenthesis + (repositories.hashCode); + + @override + String toString() => 'RepositoryListResponseDto[repositories=$repositories]'; + + Map toJson() { + final json = {}; + json[r'repositories'] = this.repositories; + return json; + } + + /// Returns a new [RepositoryListResponseDto] instance and imports its values from + /// [value] if it's a [Map], null otherwise. + // ignore: prefer_constructors_over_static_methods + static RepositoryListResponseDto? fromJson(dynamic value) { + upgradeDto(value, "RepositoryListResponseDto"); + if (value is Map) { + final json = value.cast(); + + return RepositoryListResponseDto( + repositories: LocalRepositoryDto.listFromJson(json[r'repositories']), + ); + } + 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 = RepositoryListResponseDto.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 = RepositoryListResponseDto.fromJson(entry.value); + if (value != null) { + map[entry.key] = value; + } + } + } + return map; + } + + // maps a json object with a list of RepositoryListResponseDto-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] = RepositoryListResponseDto.listFromJson(entry.value, growable: growable,); + } + } + return map; + } + + /// The list of required keys that must be present in a JSON. + static const requiredKeys = { + 'repositories', + }; +} + diff --git a/mobile/openapi/lib/model/repository_metrics_dto.dart b/mobile/openapi/lib/model/repository_metrics_dto.dart new file mode 100644 index 0000000000..cc9ce643ed --- /dev/null +++ b/mobile/openapi/lib/model/repository_metrics_dto.dart @@ -0,0 +1,150 @@ +// +// AUTO-GENERATED FILE, DO NOT MODIFY! +// +// @dart=2.18 + +// ignore_for_file: unused_element, unused_import +// ignore_for_file: always_put_required_named_parameters_first +// ignore_for_file: constant_identifier_names +// ignore_for_file: lines_longer_than_80_chars + +part of openapi.api; + +class RepositoryMetricsDto { + /// Returns a new [RepositoryMetricsDto] instance. + RepositoryMetricsDto({ + this.lastBackup, + this.lastBackupDuration, + this.lastSuccessfulBackup, + required this.sizeBytes, + }); + + /// + /// 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? lastBackup; + + /// + /// Please note: This property should have been non-nullable! Since the specification file + /// does not include a default value (using the "default:" property), however, the generated + /// source code must fall back to having a nullable type. + /// Consider adding a "default:" property in the specification file to hide this note. + /// + num? lastBackupDuration; + + /// + /// 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? lastSuccessfulBackup; + + num sizeBytes; + + @override + bool operator ==(Object other) => identical(this, other) || other is RepositoryMetricsDto && + other.lastBackup == lastBackup && + other.lastBackupDuration == lastBackupDuration && + other.lastSuccessfulBackup == lastSuccessfulBackup && + other.sizeBytes == sizeBytes; + + @override + int get hashCode => + // ignore: unnecessary_parenthesis + (lastBackup == null ? 0 : lastBackup!.hashCode) + + (lastBackupDuration == null ? 0 : lastBackupDuration!.hashCode) + + (lastSuccessfulBackup == null ? 0 : lastSuccessfulBackup!.hashCode) + + (sizeBytes.hashCode); + + @override + String toString() => 'RepositoryMetricsDto[lastBackup=$lastBackup, lastBackupDuration=$lastBackupDuration, lastSuccessfulBackup=$lastSuccessfulBackup, sizeBytes=$sizeBytes]'; + + Map toJson() { + final json = {}; + if (this.lastBackup != null) { + json[r'lastBackup'] = this.lastBackup; + } else { + // json[r'lastBackup'] = null; + } + if (this.lastBackupDuration != null) { + json[r'lastBackupDuration'] = this.lastBackupDuration; + } else { + // json[r'lastBackupDuration'] = null; + } + if (this.lastSuccessfulBackup != null) { + json[r'lastSuccessfulBackup'] = this.lastSuccessfulBackup; + } else { + // json[r'lastSuccessfulBackup'] = null; + } + json[r'sizeBytes'] = this.sizeBytes; + return json; + } + + /// Returns a new [RepositoryMetricsDto] instance and imports its values from + /// [value] if it's a [Map], null otherwise. + // ignore: prefer_constructors_over_static_methods + static RepositoryMetricsDto? fromJson(dynamic value) { + upgradeDto(value, "RepositoryMetricsDto"); + if (value is Map) { + final json = value.cast(); + + return RepositoryMetricsDto( + lastBackup: mapValueOfType(json, r'lastBackup'), + lastBackupDuration: num.parse('${json[r'lastBackupDuration']}'), + lastSuccessfulBackup: mapValueOfType(json, r'lastSuccessfulBackup'), + sizeBytes: num.parse('${json[r'sizeBytes']}'), + ); + } + 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 = RepositoryMetricsDto.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 = RepositoryMetricsDto.fromJson(entry.value); + if (value != null) { + map[entry.key] = value; + } + } + } + return map; + } + + // maps a json object with a list of RepositoryMetricsDto-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] = RepositoryMetricsDto.listFromJson(entry.value, growable: growable,); + } + } + return map; + } + + /// The list of required keys that must be present in a JSON. + static const requiredKeys = { + 'sizeBytes', + }; +} + diff --git a/mobile/openapi/lib/model/repository_snapshot_restore_from_point_request_dto.dart b/mobile/openapi/lib/model/repository_snapshot_restore_from_point_request_dto.dart new file mode 100644 index 0000000000..fcc24a0a7d --- /dev/null +++ b/mobile/openapi/lib/model/repository_snapshot_restore_from_point_request_dto.dart @@ -0,0 +1,117 @@ +// +// AUTO-GENERATED FILE, DO NOT MODIFY! +// +// @dart=2.18 + +// ignore_for_file: unused_element, unused_import +// ignore_for_file: always_put_required_named_parameters_first +// ignore_for_file: constant_identifier_names +// ignore_for_file: lines_longer_than_80_chars + +part of openapi.api; + +class RepositorySnapshotRestoreFromPointRequestDto { + /// Returns a new [RepositorySnapshotRestoreFromPointRequestDto] instance. + RepositorySnapshotRestoreFromPointRequestDto({ + this.include = const [], + this.yuccaConfig, + }); + + List include; + + /// + /// 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? yuccaConfig; + + @override + bool operator ==(Object other) => identical(this, other) || other is RepositorySnapshotRestoreFromPointRequestDto && + _deepEquality.equals(other.include, include) && + other.yuccaConfig == yuccaConfig; + + @override + int get hashCode => + // ignore: unnecessary_parenthesis + (include.hashCode) + + (yuccaConfig == null ? 0 : yuccaConfig!.hashCode); + + @override + String toString() => 'RepositorySnapshotRestoreFromPointRequestDto[include=$include, yuccaConfig=$yuccaConfig]'; + + Map toJson() { + final json = {}; + json[r'include'] = this.include; + if (this.yuccaConfig != null) { + json[r'yuccaConfig'] = this.yuccaConfig; + } else { + // json[r'yuccaConfig'] = null; + } + return json; + } + + /// Returns a new [RepositorySnapshotRestoreFromPointRequestDto] instance and imports its values from + /// [value] if it's a [Map], null otherwise. + // ignore: prefer_constructors_over_static_methods + static RepositorySnapshotRestoreFromPointRequestDto? fromJson(dynamic value) { + upgradeDto(value, "RepositorySnapshotRestoreFromPointRequestDto"); + if (value is Map) { + final json = value.cast(); + + return RepositorySnapshotRestoreFromPointRequestDto( + include: json[r'include'] is Iterable + ? (json[r'include'] as Iterable).cast().toList(growable: false) + : const [], + yuccaConfig: mapValueOfType(json, r'yuccaConfig'), + ); + } + 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 = RepositorySnapshotRestoreFromPointRequestDto.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 = RepositorySnapshotRestoreFromPointRequestDto.fromJson(entry.value); + if (value != null) { + map[entry.key] = value; + } + } + } + return map; + } + + // maps a json object with a list of RepositorySnapshotRestoreFromPointRequestDto-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] = RepositorySnapshotRestoreFromPointRequestDto.listFromJson(entry.value, growable: growable,); + } + } + return map; + } + + /// The list of required keys that must be present in a JSON. + static const requiredKeys = { + }; +} + diff --git a/mobile/openapi/lib/model/repository_snapshot_restore_request_dto.dart b/mobile/openapi/lib/model/repository_snapshot_restore_request_dto.dart new file mode 100644 index 0000000000..110d4b6eae --- /dev/null +++ b/mobile/openapi/lib/model/repository_snapshot_restore_request_dto.dart @@ -0,0 +1,117 @@ +// +// AUTO-GENERATED FILE, DO NOT MODIFY! +// +// @dart=2.18 + +// ignore_for_file: unused_element, unused_import +// ignore_for_file: always_put_required_named_parameters_first +// ignore_for_file: constant_identifier_names +// ignore_for_file: lines_longer_than_80_chars + +part of openapi.api; + +class RepositorySnapshotRestoreRequestDto { + /// Returns a new [RepositorySnapshotRestoreRequestDto] instance. + RepositorySnapshotRestoreRequestDto({ + this.include = const [], + this.target, + }); + + List include; + + /// + /// 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? target; + + @override + bool operator ==(Object other) => identical(this, other) || other is RepositorySnapshotRestoreRequestDto && + _deepEquality.equals(other.include, include) && + other.target == target; + + @override + int get hashCode => + // ignore: unnecessary_parenthesis + (include.hashCode) + + (target == null ? 0 : target!.hashCode); + + @override + String toString() => 'RepositorySnapshotRestoreRequestDto[include=$include, target=$target]'; + + Map toJson() { + final json = {}; + json[r'include'] = this.include; + if (this.target != null) { + json[r'target'] = this.target; + } else { + // json[r'target'] = null; + } + return json; + } + + /// Returns a new [RepositorySnapshotRestoreRequestDto] instance and imports its values from + /// [value] if it's a [Map], null otherwise. + // ignore: prefer_constructors_over_static_methods + static RepositorySnapshotRestoreRequestDto? fromJson(dynamic value) { + upgradeDto(value, "RepositorySnapshotRestoreRequestDto"); + if (value is Map) { + final json = value.cast(); + + return RepositorySnapshotRestoreRequestDto( + include: json[r'include'] is Iterable + ? (json[r'include'] as Iterable).cast().toList(growable: false) + : const [], + target: mapValueOfType(json, r'target'), + ); + } + 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 = RepositorySnapshotRestoreRequestDto.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 = RepositorySnapshotRestoreRequestDto.fromJson(entry.value); + if (value != null) { + map[entry.key] = value; + } + } + } + return map; + } + + // maps a json object with a list of RepositorySnapshotRestoreRequestDto-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] = RepositorySnapshotRestoreRequestDto.listFromJson(entry.value, growable: growable,); + } + } + return map; + } + + /// The list of required keys that must be present in a JSON. + static const requiredKeys = { + }; +} + diff --git a/mobile/openapi/lib/model/repository_update_request_dto.dart b/mobile/openapi/lib/model/repository_update_request_dto.dart new file mode 100644 index 0000000000..5e549a9df5 --- /dev/null +++ b/mobile/openapi/lib/model/repository_update_request_dto.dart @@ -0,0 +1,117 @@ +// +// AUTO-GENERATED FILE, DO NOT MODIFY! +// +// @dart=2.18 + +// ignore_for_file: unused_element, unused_import +// ignore_for_file: always_put_required_named_parameters_first +// ignore_for_file: constant_identifier_names +// ignore_for_file: lines_longer_than_80_chars + +part of openapi.api; + +class RepositoryUpdateRequestDto { + /// Returns a new [RepositoryUpdateRequestDto] instance. + RepositoryUpdateRequestDto({ + this.name, + this.paths = const [], + }); + + /// + /// 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? name; + + List paths; + + @override + bool operator ==(Object other) => identical(this, other) || other is RepositoryUpdateRequestDto && + other.name == name && + _deepEquality.equals(other.paths, paths); + + @override + int get hashCode => + // ignore: unnecessary_parenthesis + (name == null ? 0 : name!.hashCode) + + (paths.hashCode); + + @override + String toString() => 'RepositoryUpdateRequestDto[name=$name, paths=$paths]'; + + Map toJson() { + final json = {}; + if (this.name != null) { + json[r'name'] = this.name; + } else { + // json[r'name'] = null; + } + json[r'paths'] = this.paths; + return json; + } + + /// Returns a new [RepositoryUpdateRequestDto] instance and imports its values from + /// [value] if it's a [Map], null otherwise. + // ignore: prefer_constructors_over_static_methods + static RepositoryUpdateRequestDto? fromJson(dynamic value) { + upgradeDto(value, "RepositoryUpdateRequestDto"); + if (value is Map) { + final json = value.cast(); + + return RepositoryUpdateRequestDto( + name: mapValueOfType(json, r'name'), + paths: json[r'paths'] is Iterable + ? (json[r'paths'] as Iterable).cast().toList(growable: false) + : const [], + ); + } + 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 = RepositoryUpdateRequestDto.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 = RepositoryUpdateRequestDto.fromJson(entry.value); + if (value != null) { + map[entry.key] = value; + } + } + } + return map; + } + + // maps a json object with a list of RepositoryUpdateRequestDto-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] = RepositoryUpdateRequestDto.listFromJson(entry.value, growable: growable,); + } + } + return map; + } + + /// The list of required keys that must be present in a JSON. + static const requiredKeys = { + }; +} + diff --git a/mobile/openapi/lib/model/repository_update_response_dto.dart b/mobile/openapi/lib/model/repository_update_response_dto.dart new file mode 100644 index 0000000000..cba26f1092 --- /dev/null +++ b/mobile/openapi/lib/model/repository_update_response_dto.dart @@ -0,0 +1,99 @@ +// +// AUTO-GENERATED FILE, DO NOT MODIFY! +// +// @dart=2.18 + +// ignore_for_file: unused_element, unused_import +// ignore_for_file: always_put_required_named_parameters_first +// ignore_for_file: constant_identifier_names +// ignore_for_file: lines_longer_than_80_chars + +part of openapi.api; + +class RepositoryUpdateResponseDto { + /// Returns a new [RepositoryUpdateResponseDto] instance. + RepositoryUpdateResponseDto({ + required this.repository, + }); + + LocalRepositoryDto repository; + + @override + bool operator ==(Object other) => identical(this, other) || other is RepositoryUpdateResponseDto && + other.repository == repository; + + @override + int get hashCode => + // ignore: unnecessary_parenthesis + (repository.hashCode); + + @override + String toString() => 'RepositoryUpdateResponseDto[repository=$repository]'; + + Map toJson() { + final json = {}; + json[r'repository'] = this.repository; + return json; + } + + /// Returns a new [RepositoryUpdateResponseDto] instance and imports its values from + /// [value] if it's a [Map], null otherwise. + // ignore: prefer_constructors_over_static_methods + static RepositoryUpdateResponseDto? fromJson(dynamic value) { + upgradeDto(value, "RepositoryUpdateResponseDto"); + if (value is Map) { + final json = value.cast(); + + return RepositoryUpdateResponseDto( + repository: LocalRepositoryDto.fromJson(json[r'repository'])!, + ); + } + 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 = RepositoryUpdateResponseDto.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 = RepositoryUpdateResponseDto.fromJson(entry.value); + if (value != null) { + map[entry.key] = value; + } + } + } + return map; + } + + // maps a json object with a list of RepositoryUpdateResponseDto-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] = RepositoryUpdateResponseDto.listFromJson(entry.value, growable: growable,); + } + } + return map; + } + + /// The list of required keys that must be present in a JSON. + static const requiredKeys = { + 'repository', + }; +} + diff --git a/mobile/openapi/lib/model/run_dto.dart b/mobile/openapi/lib/model/run_dto.dart new file mode 100644 index 0000000000..4c5afbbaa1 --- /dev/null +++ b/mobile/openapi/lib/model/run_dto.dart @@ -0,0 +1,131 @@ +// +// AUTO-GENERATED FILE, DO NOT MODIFY! +// +// @dart=2.18 + +// ignore_for_file: unused_element, unused_import +// ignore_for_file: always_put_required_named_parameters_first +// ignore_for_file: constant_identifier_names +// ignore_for_file: lines_longer_than_80_chars + +part of openapi.api; + +class RunDto { + /// Returns a new [RunDto] instance. + RunDto({ + required this.end, + required this.id, + required this.logFilePath, + required this.start, + required this.status, + }); + + String end; + + String id; + + String logFilePath; + + String start; + + RunStatus status; + + @override + bool operator ==(Object other) => identical(this, other) || other is RunDto && + other.end == end && + other.id == id && + other.logFilePath == logFilePath && + other.start == start && + other.status == status; + + @override + int get hashCode => + // ignore: unnecessary_parenthesis + (end.hashCode) + + (id.hashCode) + + (logFilePath.hashCode) + + (start.hashCode) + + (status.hashCode); + + @override + String toString() => 'RunDto[end=$end, id=$id, logFilePath=$logFilePath, start=$start, status=$status]'; + + Map toJson() { + final json = {}; + json[r'end'] = this.end; + json[r'id'] = this.id; + json[r'logFilePath'] = this.logFilePath; + json[r'start'] = this.start; + json[r'status'] = this.status; + return json; + } + + /// Returns a new [RunDto] instance and imports its values from + /// [value] if it's a [Map], null otherwise. + // ignore: prefer_constructors_over_static_methods + static RunDto? fromJson(dynamic value) { + upgradeDto(value, "RunDto"); + if (value is Map) { + final json = value.cast(); + + return RunDto( + end: mapValueOfType(json, r'end')!, + id: mapValueOfType(json, r'id')!, + logFilePath: mapValueOfType(json, r'logFilePath')!, + start: mapValueOfType(json, r'start')!, + status: RunStatus.fromJson(json[r'status'])!, + ); + } + 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 = RunDto.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 = RunDto.fromJson(entry.value); + if (value != null) { + map[entry.key] = value; + } + } + } + return map; + } + + // maps a json object with a list of RunDto-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] = RunDto.listFromJson(entry.value, growable: growable,); + } + } + return map; + } + + /// The list of required keys that must be present in a JSON. + static const requiredKeys = { + 'end', + 'id', + 'logFilePath', + 'start', + 'status', + }; +} + diff --git a/mobile/openapi/lib/model/run_history_response_dto.dart b/mobile/openapi/lib/model/run_history_response_dto.dart new file mode 100644 index 0000000000..49a5b6dadf --- /dev/null +++ b/mobile/openapi/lib/model/run_history_response_dto.dart @@ -0,0 +1,99 @@ +// +// AUTO-GENERATED FILE, DO NOT MODIFY! +// +// @dart=2.18 + +// ignore_for_file: unused_element, unused_import +// ignore_for_file: always_put_required_named_parameters_first +// ignore_for_file: constant_identifier_names +// ignore_for_file: lines_longer_than_80_chars + +part of openapi.api; + +class RunHistoryResponseDto { + /// Returns a new [RunHistoryResponseDto] instance. + RunHistoryResponseDto({ + this.runs = const [], + }); + + List runs; + + @override + bool operator ==(Object other) => identical(this, other) || other is RunHistoryResponseDto && + _deepEquality.equals(other.runs, runs); + + @override + int get hashCode => + // ignore: unnecessary_parenthesis + (runs.hashCode); + + @override + String toString() => 'RunHistoryResponseDto[runs=$runs]'; + + Map toJson() { + final json = {}; + json[r'runs'] = this.runs; + return json; + } + + /// Returns a new [RunHistoryResponseDto] instance and imports its values from + /// [value] if it's a [Map], null otherwise. + // ignore: prefer_constructors_over_static_methods + static RunHistoryResponseDto? fromJson(dynamic value) { + upgradeDto(value, "RunHistoryResponseDto"); + if (value is Map) { + final json = value.cast(); + + return RunHistoryResponseDto( + runs: RunDto.listFromJson(json[r'runs']), + ); + } + 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 = RunHistoryResponseDto.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 = RunHistoryResponseDto.fromJson(entry.value); + if (value != null) { + map[entry.key] = value; + } + } + } + return map; + } + + // maps a json object with a list of RunHistoryResponseDto-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] = RunHistoryResponseDto.listFromJson(entry.value, growable: growable,); + } + } + return map; + } + + /// The list of required keys that must be present in a JSON. + static const requiredKeys = { + 'runs', + }; +} + diff --git a/mobile/openapi/lib/model/run_status.dart b/mobile/openapi/lib/model/run_status.dart new file mode 100644 index 0000000000..54ae25920e --- /dev/null +++ b/mobile/openapi/lib/model/run_status.dart @@ -0,0 +1,88 @@ +// +// AUTO-GENERATED FILE, DO NOT MODIFY! +// +// @dart=2.18 + +// ignore_for_file: unused_element, unused_import +// ignore_for_file: always_put_required_named_parameters_first +// ignore_for_file: constant_identifier_names +// ignore_for_file: lines_longer_than_80_chars + +part of openapi.api; + + +class RunStatus { + /// Instantiate a new enum with the provided [value]. + const RunStatus._(this.value); + + /// The underlying value of this enum member. + final String value; + + @override + String toString() => value; + + String toJson() => value; + + static const incomplete = RunStatus._(r'incomplete'); + static const complete = RunStatus._(r'complete'); + static const failed = RunStatus._(r'failed'); + + /// List of all possible values in this [enum][RunStatus]. + static const values = [ + incomplete, + complete, + failed, + ]; + + static RunStatus? fromJson(dynamic value) => RunStatusTypeTransformer().decode(value); + + static List listFromJson(dynamic json, {bool growable = false,}) { + final result = []; + if (json is List && json.isNotEmpty) { + for (final row in json) { + final value = RunStatus.fromJson(row); + if (value != null) { + result.add(value); + } + } + } + return result.toList(growable: growable); + } +} + +/// Transformation class that can [encode] an instance of [RunStatus] to String, +/// and [decode] dynamic data back to [RunStatus]. +class RunStatusTypeTransformer { + factory RunStatusTypeTransformer() => _instance ??= const RunStatusTypeTransformer._(); + + const RunStatusTypeTransformer._(); + + String encode(RunStatus data) => data.value; + + /// Decodes a [dynamic value][data] to a RunStatus. + /// + /// If [allowNull] is true and the [dynamic value][data] cannot be decoded successfully, + /// then null is returned. However, if [allowNull] is false and the [dynamic value][data] + /// cannot be decoded successfully, then an [UnimplementedError] is thrown. + /// + /// The [allowNull] is very handy when an API changes and a new enum value is added or removed, + /// and users are still using an old app with the old code. + RunStatus? decode(dynamic data, {bool allowNull = true}) { + if (data != null) { + switch (data) { + case r'incomplete': return RunStatus.incomplete; + case r'complete': return RunStatus.complete; + case r'failed': return RunStatus.failed; + default: + if (!allowNull) { + throw ArgumentError('Unknown enum value to decode: $data'); + } + } + } + return null; + } + + /// Singleton [RunStatusTypeTransformer] instance. + static RunStatusTypeTransformer? _instance; +} + diff --git a/mobile/openapi/lib/model/running_task_dto.dart b/mobile/openapi/lib/model/running_task_dto.dart new file mode 100644 index 0000000000..77fcdedba8 --- /dev/null +++ b/mobile/openapi/lib/model/running_task_dto.dart @@ -0,0 +1,131 @@ +// +// AUTO-GENERATED FILE, DO NOT MODIFY! +// +// @dart=2.18 + +// ignore_for_file: unused_element, unused_import +// ignore_for_file: always_put_required_named_parameters_first +// ignore_for_file: constant_identifier_names +// ignore_for_file: lines_longer_than_80_chars + +part of openapi.api; + +class RunningTaskDto { + /// Returns a new [RunningTaskDto] instance. + RunningTaskDto({ + this.logId, + required this.parentId, + this.scheduleStatus = const [], + required this.type, + }); + + /// + /// 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? logId; + + String parentId; + + List scheduleStatus; + + TaskType type; + + @override + bool operator ==(Object other) => identical(this, other) || other is RunningTaskDto && + other.logId == logId && + other.parentId == parentId && + _deepEquality.equals(other.scheduleStatus, scheduleStatus) && + other.type == type; + + @override + int get hashCode => + // ignore: unnecessary_parenthesis + (logId == null ? 0 : logId!.hashCode) + + (parentId.hashCode) + + (scheduleStatus.hashCode) + + (type.hashCode); + + @override + String toString() => 'RunningTaskDto[logId=$logId, parentId=$parentId, scheduleStatus=$scheduleStatus, type=$type]'; + + Map toJson() { + final json = {}; + if (this.logId != null) { + json[r'logId'] = this.logId; + } else { + // json[r'logId'] = null; + } + json[r'parentId'] = this.parentId; + json[r'scheduleStatus'] = this.scheduleStatus; + json[r'type'] = this.type; + return json; + } + + /// Returns a new [RunningTaskDto] instance and imports its values from + /// [value] if it's a [Map], null otherwise. + // ignore: prefer_constructors_over_static_methods + static RunningTaskDto? fromJson(dynamic value) { + upgradeDto(value, "RunningTaskDto"); + if (value is Map) { + final json = value.cast(); + + return RunningTaskDto( + logId: mapValueOfType(json, r'logId'), + parentId: mapValueOfType(json, r'parentId')!, + scheduleStatus: ActiveScheduleItemDto.listFromJson(json[r'scheduleStatus']), + type: TaskType.fromJson(json[r'type'])!, + ); + } + 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 = RunningTaskDto.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 = RunningTaskDto.fromJson(entry.value); + if (value != null) { + map[entry.key] = value; + } + } + } + return map; + } + + // maps a json object with a list of RunningTaskDto-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] = RunningTaskDto.listFromJson(entry.value, growable: growable,); + } + } + return map; + } + + /// The list of required keys that must be present in a JSON. + static const requiredKeys = { + 'parentId', + 'type', + }; +} + diff --git a/mobile/openapi/lib/model/running_task_list_response.dart b/mobile/openapi/lib/model/running_task_list_response.dart new file mode 100644 index 0000000000..4c5a6376cf --- /dev/null +++ b/mobile/openapi/lib/model/running_task_list_response.dart @@ -0,0 +1,99 @@ +// +// AUTO-GENERATED FILE, DO NOT MODIFY! +// +// @dart=2.18 + +// ignore_for_file: unused_element, unused_import +// ignore_for_file: always_put_required_named_parameters_first +// ignore_for_file: constant_identifier_names +// ignore_for_file: lines_longer_than_80_chars + +part of openapi.api; + +class RunningTaskListResponse { + /// Returns a new [RunningTaskListResponse] instance. + RunningTaskListResponse({ + this.tasks = const [], + }); + + List tasks; + + @override + bool operator ==(Object other) => identical(this, other) || other is RunningTaskListResponse && + _deepEquality.equals(other.tasks, tasks); + + @override + int get hashCode => + // ignore: unnecessary_parenthesis + (tasks.hashCode); + + @override + String toString() => 'RunningTaskListResponse[tasks=$tasks]'; + + Map toJson() { + final json = {}; + json[r'tasks'] = this.tasks; + return json; + } + + /// Returns a new [RunningTaskListResponse] instance and imports its values from + /// [value] if it's a [Map], null otherwise. + // ignore: prefer_constructors_over_static_methods + static RunningTaskListResponse? fromJson(dynamic value) { + upgradeDto(value, "RunningTaskListResponse"); + if (value is Map) { + final json = value.cast(); + + return RunningTaskListResponse( + tasks: RunningTaskDto.listFromJson(json[r'tasks']), + ); + } + 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 = RunningTaskListResponse.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 = RunningTaskListResponse.fromJson(entry.value); + if (value != null) { + map[entry.key] = value; + } + } + } + return map; + } + + // maps a json object with a list of RunningTaskListResponse-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] = RunningTaskListResponse.listFromJson(entry.value, growable: growable,); + } + } + return map; + } + + /// The list of required keys that must be present in a JSON. + static const requiredKeys = { + 'tasks', + }; +} + diff --git a/mobile/openapi/lib/model/schedule_create_request_dto.dart b/mobile/openapi/lib/model/schedule_create_request_dto.dart new file mode 100644 index 0000000000..646b333d7a --- /dev/null +++ b/mobile/openapi/lib/model/schedule_create_request_dto.dart @@ -0,0 +1,117 @@ +// +// AUTO-GENERATED FILE, DO NOT MODIFY! +// +// @dart=2.18 + +// ignore_for_file: unused_element, unused_import +// ignore_for_file: always_put_required_named_parameters_first +// ignore_for_file: constant_identifier_names +// ignore_for_file: lines_longer_than_80_chars + +part of openapi.api; + +class ScheduleCreateRequestDto { + /// Returns a new [ScheduleCreateRequestDto] instance. + ScheduleCreateRequestDto({ + required this.cron, + required this.name, + this.repositories = const [], + }); + + String cron; + + String name; + + List repositories; + + @override + bool operator ==(Object other) => identical(this, other) || other is ScheduleCreateRequestDto && + other.cron == cron && + other.name == name && + _deepEquality.equals(other.repositories, repositories); + + @override + int get hashCode => + // ignore: unnecessary_parenthesis + (cron.hashCode) + + (name.hashCode) + + (repositories.hashCode); + + @override + String toString() => 'ScheduleCreateRequestDto[cron=$cron, name=$name, repositories=$repositories]'; + + Map toJson() { + final json = {}; + json[r'cron'] = this.cron; + json[r'name'] = this.name; + json[r'repositories'] = this.repositories; + return json; + } + + /// Returns a new [ScheduleCreateRequestDto] instance and imports its values from + /// [value] if it's a [Map], null otherwise. + // ignore: prefer_constructors_over_static_methods + static ScheduleCreateRequestDto? fromJson(dynamic value) { + upgradeDto(value, "ScheduleCreateRequestDto"); + if (value is Map) { + final json = value.cast(); + + return ScheduleCreateRequestDto( + cron: mapValueOfType(json, r'cron')!, + name: mapValueOfType(json, r'name')!, + repositories: json[r'repositories'] is Iterable + ? (json[r'repositories'] as Iterable).cast().toList(growable: false) + : const [], + ); + } + 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 = ScheduleCreateRequestDto.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 = ScheduleCreateRequestDto.fromJson(entry.value); + if (value != null) { + map[entry.key] = value; + } + } + } + return map; + } + + // maps a json object with a list of ScheduleCreateRequestDto-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] = ScheduleCreateRequestDto.listFromJson(entry.value, growable: growable,); + } + } + return map; + } + + /// The list of required keys that must be present in a JSON. + static const requiredKeys = { + 'cron', + 'name', + 'repositories', + }; +} + diff --git a/mobile/openapi/lib/model/schedule_create_response_dto.dart b/mobile/openapi/lib/model/schedule_create_response_dto.dart new file mode 100644 index 0000000000..965dd0bb95 --- /dev/null +++ b/mobile/openapi/lib/model/schedule_create_response_dto.dart @@ -0,0 +1,99 @@ +// +// AUTO-GENERATED FILE, DO NOT MODIFY! +// +// @dart=2.18 + +// ignore_for_file: unused_element, unused_import +// ignore_for_file: always_put_required_named_parameters_first +// ignore_for_file: constant_identifier_names +// ignore_for_file: lines_longer_than_80_chars + +part of openapi.api; + +class ScheduleCreateResponseDto { + /// Returns a new [ScheduleCreateResponseDto] instance. + ScheduleCreateResponseDto({ + required this.schedule, + }); + + ScheduleDto schedule; + + @override + bool operator ==(Object other) => identical(this, other) || other is ScheduleCreateResponseDto && + other.schedule == schedule; + + @override + int get hashCode => + // ignore: unnecessary_parenthesis + (schedule.hashCode); + + @override + String toString() => 'ScheduleCreateResponseDto[schedule=$schedule]'; + + Map toJson() { + final json = {}; + json[r'schedule'] = this.schedule; + return json; + } + + /// Returns a new [ScheduleCreateResponseDto] instance and imports its values from + /// [value] if it's a [Map], null otherwise. + // ignore: prefer_constructors_over_static_methods + static ScheduleCreateResponseDto? fromJson(dynamic value) { + upgradeDto(value, "ScheduleCreateResponseDto"); + if (value is Map) { + final json = value.cast(); + + return ScheduleCreateResponseDto( + schedule: ScheduleDto.fromJson(json[r'schedule'])!, + ); + } + 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 = ScheduleCreateResponseDto.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 = ScheduleCreateResponseDto.fromJson(entry.value); + if (value != null) { + map[entry.key] = value; + } + } + } + return map; + } + + // maps a json object with a list of ScheduleCreateResponseDto-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] = ScheduleCreateResponseDto.listFromJson(entry.value, growable: growable,); + } + } + return map; + } + + /// The list of required keys that must be present in a JSON. + static const requiredKeys = { + 'schedule', + }; +} + diff --git a/mobile/openapi/lib/model/schedule_dto.dart b/mobile/openapi/lib/model/schedule_dto.dart new file mode 100644 index 0000000000..c81446b117 --- /dev/null +++ b/mobile/openapi/lib/model/schedule_dto.dart @@ -0,0 +1,167 @@ +// +// AUTO-GENERATED FILE, DO NOT MODIFY! +// +// @dart=2.18 + +// ignore_for_file: unused_element, unused_import +// ignore_for_file: always_put_required_named_parameters_first +// ignore_for_file: constant_identifier_names +// ignore_for_file: lines_longer_than_80_chars + +part of openapi.api; + +class ScheduleDto { + /// Returns a new [ScheduleDto] instance. + ScheduleDto({ + required this.cron, + required this.id, + this.lastFinished, + this.lastRun, + required this.name, + required this.paused, + this.repositories = const [], + }); + + String cron; + + String id; + + /// + /// 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? lastFinished; + + /// + /// 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? lastRun; + + String name; + + bool paused; + + List repositories; + + @override + bool operator ==(Object other) => identical(this, other) || other is ScheduleDto && + other.cron == cron && + other.id == id && + other.lastFinished == lastFinished && + other.lastRun == lastRun && + other.name == name && + other.paused == paused && + _deepEquality.equals(other.repositories, repositories); + + @override + int get hashCode => + // ignore: unnecessary_parenthesis + (cron.hashCode) + + (id.hashCode) + + (lastFinished == null ? 0 : lastFinished!.hashCode) + + (lastRun == null ? 0 : lastRun!.hashCode) + + (name.hashCode) + + (paused.hashCode) + + (repositories.hashCode); + + @override + String toString() => 'ScheduleDto[cron=$cron, id=$id, lastFinished=$lastFinished, lastRun=$lastRun, name=$name, paused=$paused, repositories=$repositories]'; + + Map toJson() { + final json = {}; + json[r'cron'] = this.cron; + json[r'id'] = this.id; + if (this.lastFinished != null) { + json[r'lastFinished'] = this.lastFinished; + } else { + // json[r'lastFinished'] = null; + } + if (this.lastRun != null) { + json[r'lastRun'] = this.lastRun; + } else { + // json[r'lastRun'] = null; + } + json[r'name'] = this.name; + json[r'paused'] = this.paused; + json[r'repositories'] = this.repositories; + return json; + } + + /// Returns a new [ScheduleDto] instance and imports its values from + /// [value] if it's a [Map], null otherwise. + // ignore: prefer_constructors_over_static_methods + static ScheduleDto? fromJson(dynamic value) { + upgradeDto(value, "ScheduleDto"); + if (value is Map) { + final json = value.cast(); + + return ScheduleDto( + cron: mapValueOfType(json, r'cron')!, + id: mapValueOfType(json, r'id')!, + lastFinished: mapValueOfType(json, r'lastFinished'), + lastRun: mapValueOfType(json, r'lastRun'), + name: mapValueOfType(json, r'name')!, + paused: mapValueOfType(json, r'paused')!, + repositories: json[r'repositories'] is Iterable + ? (json[r'repositories'] as Iterable).cast().toList(growable: false) + : const [], + ); + } + 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 = ScheduleDto.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 = ScheduleDto.fromJson(entry.value); + if (value != null) { + map[entry.key] = value; + } + } + } + return map; + } + + // maps a json object with a list of ScheduleDto-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] = ScheduleDto.listFromJson(entry.value, growable: growable,); + } + } + return map; + } + + /// The list of required keys that must be present in a JSON. + static const requiredKeys = { + 'cron', + 'id', + 'name', + 'paused', + 'repositories', + }; +} + diff --git a/mobile/openapi/lib/model/schedule_list_response_dto.dart b/mobile/openapi/lib/model/schedule_list_response_dto.dart new file mode 100644 index 0000000000..e3cf56aca8 --- /dev/null +++ b/mobile/openapi/lib/model/schedule_list_response_dto.dart @@ -0,0 +1,99 @@ +// +// AUTO-GENERATED FILE, DO NOT MODIFY! +// +// @dart=2.18 + +// ignore_for_file: unused_element, unused_import +// ignore_for_file: always_put_required_named_parameters_first +// ignore_for_file: constant_identifier_names +// ignore_for_file: lines_longer_than_80_chars + +part of openapi.api; + +class ScheduleListResponseDto { + /// Returns a new [ScheduleListResponseDto] instance. + ScheduleListResponseDto({ + this.schedules = const [], + }); + + List schedules; + + @override + bool operator ==(Object other) => identical(this, other) || other is ScheduleListResponseDto && + _deepEquality.equals(other.schedules, schedules); + + @override + int get hashCode => + // ignore: unnecessary_parenthesis + (schedules.hashCode); + + @override + String toString() => 'ScheduleListResponseDto[schedules=$schedules]'; + + Map toJson() { + final json = {}; + json[r'schedules'] = this.schedules; + return json; + } + + /// Returns a new [ScheduleListResponseDto] instance and imports its values from + /// [value] if it's a [Map], null otherwise. + // ignore: prefer_constructors_over_static_methods + static ScheduleListResponseDto? fromJson(dynamic value) { + upgradeDto(value, "ScheduleListResponseDto"); + if (value is Map) { + final json = value.cast(); + + return ScheduleListResponseDto( + schedules: ScheduleDto.listFromJson(json[r'schedules']), + ); + } + 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 = ScheduleListResponseDto.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 = ScheduleListResponseDto.fromJson(entry.value); + if (value != null) { + map[entry.key] = value; + } + } + } + return map; + } + + // maps a json object with a list of ScheduleListResponseDto-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] = ScheduleListResponseDto.listFromJson(entry.value, growable: growable,); + } + } + return map; + } + + /// The list of required keys that must be present in a JSON. + static const requiredKeys = { + 'schedules', + }; +} + diff --git a/mobile/openapi/lib/model/schedule_update_request_dto.dart b/mobile/openapi/lib/model/schedule_update_request_dto.dart new file mode 100644 index 0000000000..88c0c9d65c --- /dev/null +++ b/mobile/openapi/lib/model/schedule_update_request_dto.dart @@ -0,0 +1,151 @@ +// +// AUTO-GENERATED FILE, DO NOT MODIFY! +// +// @dart=2.18 + +// ignore_for_file: unused_element, unused_import +// ignore_for_file: always_put_required_named_parameters_first +// ignore_for_file: constant_identifier_names +// ignore_for_file: lines_longer_than_80_chars + +part of openapi.api; + +class ScheduleUpdateRequestDto { + /// Returns a new [ScheduleUpdateRequestDto] instance. + ScheduleUpdateRequestDto({ + this.cron, + this.name, + this.paused, + this.repositories = const [], + }); + + /// + /// 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? cron; + + /// + /// 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? name; + + /// + /// 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? paused; + + List repositories; + + @override + bool operator ==(Object other) => identical(this, other) || other is ScheduleUpdateRequestDto && + other.cron == cron && + other.name == name && + other.paused == paused && + _deepEquality.equals(other.repositories, repositories); + + @override + int get hashCode => + // ignore: unnecessary_parenthesis + (cron == null ? 0 : cron!.hashCode) + + (name == null ? 0 : name!.hashCode) + + (paused == null ? 0 : paused!.hashCode) + + (repositories.hashCode); + + @override + String toString() => 'ScheduleUpdateRequestDto[cron=$cron, name=$name, paused=$paused, repositories=$repositories]'; + + Map toJson() { + final json = {}; + if (this.cron != null) { + json[r'cron'] = this.cron; + } else { + // json[r'cron'] = null; + } + if (this.name != null) { + json[r'name'] = this.name; + } else { + // json[r'name'] = null; + } + if (this.paused != null) { + json[r'paused'] = this.paused; + } else { + // json[r'paused'] = null; + } + json[r'repositories'] = this.repositories; + return json; + } + + /// Returns a new [ScheduleUpdateRequestDto] instance and imports its values from + /// [value] if it's a [Map], null otherwise. + // ignore: prefer_constructors_over_static_methods + static ScheduleUpdateRequestDto? fromJson(dynamic value) { + upgradeDto(value, "ScheduleUpdateRequestDto"); + if (value is Map) { + final json = value.cast(); + + return ScheduleUpdateRequestDto( + cron: mapValueOfType(json, r'cron'), + name: mapValueOfType(json, r'name'), + paused: mapValueOfType(json, r'paused'), + repositories: json[r'repositories'] is Iterable + ? (json[r'repositories'] as Iterable).cast().toList(growable: false) + : const [], + ); + } + 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 = ScheduleUpdateRequestDto.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 = ScheduleUpdateRequestDto.fromJson(entry.value); + if (value != null) { + map[entry.key] = value; + } + } + } + return map; + } + + // maps a json object with a list of ScheduleUpdateRequestDto-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] = ScheduleUpdateRequestDto.listFromJson(entry.value, growable: growable,); + } + } + return map; + } + + /// The list of required keys that must be present in a JSON. + static const requiredKeys = { + }; +} + diff --git a/mobile/openapi/lib/model/schedule_update_response_dto.dart b/mobile/openapi/lib/model/schedule_update_response_dto.dart new file mode 100644 index 0000000000..28b73c6b71 --- /dev/null +++ b/mobile/openapi/lib/model/schedule_update_response_dto.dart @@ -0,0 +1,99 @@ +// +// AUTO-GENERATED FILE, DO NOT MODIFY! +// +// @dart=2.18 + +// ignore_for_file: unused_element, unused_import +// ignore_for_file: always_put_required_named_parameters_first +// ignore_for_file: constant_identifier_names +// ignore_for_file: lines_longer_than_80_chars + +part of openapi.api; + +class ScheduleUpdateResponseDto { + /// Returns a new [ScheduleUpdateResponseDto] instance. + ScheduleUpdateResponseDto({ + required this.schedule, + }); + + ScheduleDto schedule; + + @override + bool operator ==(Object other) => identical(this, other) || other is ScheduleUpdateResponseDto && + other.schedule == schedule; + + @override + int get hashCode => + // ignore: unnecessary_parenthesis + (schedule.hashCode); + + @override + String toString() => 'ScheduleUpdateResponseDto[schedule=$schedule]'; + + Map toJson() { + final json = {}; + json[r'schedule'] = this.schedule; + return json; + } + + /// Returns a new [ScheduleUpdateResponseDto] instance and imports its values from + /// [value] if it's a [Map], null otherwise. + // ignore: prefer_constructors_over_static_methods + static ScheduleUpdateResponseDto? fromJson(dynamic value) { + upgradeDto(value, "ScheduleUpdateResponseDto"); + if (value is Map) { + final json = value.cast(); + + return ScheduleUpdateResponseDto( + schedule: ScheduleDto.fromJson(json[r'schedule'])!, + ); + } + 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 = ScheduleUpdateResponseDto.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 = ScheduleUpdateResponseDto.fromJson(entry.value); + if (value != null) { + map[entry.key] = value; + } + } + } + return map; + } + + // maps a json object with a list of ScheduleUpdateResponseDto-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] = ScheduleUpdateResponseDto.listFromJson(entry.value, growable: growable,); + } + } + return map; + } + + /// The list of required keys that must be present in a JSON. + static const requiredKeys = { + 'schedule', + }; +} + diff --git a/mobile/openapi/lib/model/snapshot_dto.dart b/mobile/openapi/lib/model/snapshot_dto.dart new file mode 100644 index 0000000000..d366f15136 --- /dev/null +++ b/mobile/openapi/lib/model/snapshot_dto.dart @@ -0,0 +1,117 @@ +// +// AUTO-GENERATED FILE, DO NOT MODIFY! +// +// @dart=2.18 + +// ignore_for_file: unused_element, unused_import +// ignore_for_file: always_put_required_named_parameters_first +// ignore_for_file: constant_identifier_names +// ignore_for_file: lines_longer_than_80_chars + +part of openapi.api; + +class SnapshotDto { + /// Returns a new [SnapshotDto] instance. + SnapshotDto({ + required this.id, + this.paths = const [], + required this.time, + }); + + String id; + + List paths; + + String time; + + @override + bool operator ==(Object other) => identical(this, other) || other is SnapshotDto && + other.id == id && + _deepEquality.equals(other.paths, paths) && + other.time == time; + + @override + int get hashCode => + // ignore: unnecessary_parenthesis + (id.hashCode) + + (paths.hashCode) + + (time.hashCode); + + @override + String toString() => 'SnapshotDto[id=$id, paths=$paths, time=$time]'; + + Map toJson() { + final json = {}; + json[r'id'] = this.id; + json[r'paths'] = this.paths; + json[r'time'] = this.time; + return json; + } + + /// Returns a new [SnapshotDto] instance and imports its values from + /// [value] if it's a [Map], null otherwise. + // ignore: prefer_constructors_over_static_methods + static SnapshotDto? fromJson(dynamic value) { + upgradeDto(value, "SnapshotDto"); + if (value is Map) { + final json = value.cast(); + + return SnapshotDto( + id: mapValueOfType(json, r'id')!, + paths: json[r'paths'] is Iterable + ? (json[r'paths'] as Iterable).cast().toList(growable: false) + : const [], + time: mapValueOfType(json, r'time')!, + ); + } + 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 = SnapshotDto.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 = SnapshotDto.fromJson(entry.value); + if (value != null) { + map[entry.key] = value; + } + } + } + return map; + } + + // maps a json object with a list of SnapshotDto-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] = SnapshotDto.listFromJson(entry.value, growable: growable,); + } + } + return map; + } + + /// The list of required keys that must be present in a JSON. + static const requiredKeys = { + 'id', + 'paths', + 'time', + }; +} + diff --git a/mobile/openapi/lib/model/task_status.dart b/mobile/openapi/lib/model/task_status.dart new file mode 100644 index 0000000000..95aaa2acdd --- /dev/null +++ b/mobile/openapi/lib/model/task_status.dart @@ -0,0 +1,88 @@ +// +// AUTO-GENERATED FILE, DO NOT MODIFY! +// +// @dart=2.18 + +// ignore_for_file: unused_element, unused_import +// ignore_for_file: always_put_required_named_parameters_first +// ignore_for_file: constant_identifier_names +// ignore_for_file: lines_longer_than_80_chars + +part of openapi.api; + + +class TaskStatus { + /// Instantiate a new enum with the provided [value]. + const TaskStatus._(this.value); + + /// The underlying value of this enum member. + final String value; + + @override + String toString() => value; + + String toJson() => value; + + static const incomplete = TaskStatus._(r'incomplete'); + static const complete = TaskStatus._(r'complete'); + static const failed = TaskStatus._(r'failed'); + + /// List of all possible values in this [enum][TaskStatus]. + static const values = [ + incomplete, + complete, + failed, + ]; + + static TaskStatus? fromJson(dynamic value) => TaskStatusTypeTransformer().decode(value); + + static List listFromJson(dynamic json, {bool growable = false,}) { + final result = []; + if (json is List && json.isNotEmpty) { + for (final row in json) { + final value = TaskStatus.fromJson(row); + if (value != null) { + result.add(value); + } + } + } + return result.toList(growable: growable); + } +} + +/// Transformation class that can [encode] an instance of [TaskStatus] to String, +/// and [decode] dynamic data back to [TaskStatus]. +class TaskStatusTypeTransformer { + factory TaskStatusTypeTransformer() => _instance ??= const TaskStatusTypeTransformer._(); + + const TaskStatusTypeTransformer._(); + + String encode(TaskStatus data) => data.value; + + /// Decodes a [dynamic value][data] to a TaskStatus. + /// + /// If [allowNull] is true and the [dynamic value][data] cannot be decoded successfully, + /// then null is returned. However, if [allowNull] is false and the [dynamic value][data] + /// cannot be decoded successfully, then an [UnimplementedError] is thrown. + /// + /// The [allowNull] is very handy when an API changes and a new enum value is added or removed, + /// and users are still using an old app with the old code. + TaskStatus? decode(dynamic data, {bool allowNull = true}) { + if (data != null) { + switch (data) { + case r'incomplete': return TaskStatus.incomplete; + case r'complete': return TaskStatus.complete; + case r'failed': return TaskStatus.failed; + default: + if (!allowNull) { + throw ArgumentError('Unknown enum value to decode: $data'); + } + } + } + return null; + } + + /// Singleton [TaskStatusTypeTransformer] instance. + static TaskStatusTypeTransformer? _instance; +} + diff --git a/mobile/openapi/lib/model/task_type.dart b/mobile/openapi/lib/model/task_type.dart new file mode 100644 index 0000000000..880aac2d39 --- /dev/null +++ b/mobile/openapi/lib/model/task_type.dart @@ -0,0 +1,91 @@ +// +// AUTO-GENERATED FILE, DO NOT MODIFY! +// +// @dart=2.18 + +// ignore_for_file: unused_element, unused_import +// ignore_for_file: always_put_required_named_parameters_first +// ignore_for_file: constant_identifier_names +// ignore_for_file: lines_longer_than_80_chars + +part of openapi.api; + + +class TaskType { + /// Instantiate a new enum with the provided [value]. + const TaskType._(this.value); + + /// The underlying value of this enum member. + final String value; + + @override + String toString() => value; + + String toJson() => value; + + static const schedule = TaskType._(r'schedule'); + static const restore = TaskType._(r'restore'); + static const backup = TaskType._(r'backup'); + static const forget = TaskType._(r'forget'); + + /// List of all possible values in this [enum][TaskType]. + static const values = [ + schedule, + restore, + backup, + forget, + ]; + + static TaskType? fromJson(dynamic value) => TaskTypeTypeTransformer().decode(value); + + static List listFromJson(dynamic json, {bool growable = false,}) { + final result = []; + if (json is List && json.isNotEmpty) { + for (final row in json) { + final value = TaskType.fromJson(row); + if (value != null) { + result.add(value); + } + } + } + return result.toList(growable: growable); + } +} + +/// Transformation class that can [encode] an instance of [TaskType] to String, +/// and [decode] dynamic data back to [TaskType]. +class TaskTypeTypeTransformer { + factory TaskTypeTypeTransformer() => _instance ??= const TaskTypeTypeTransformer._(); + + const TaskTypeTypeTransformer._(); + + String encode(TaskType data) => data.value; + + /// Decodes a [dynamic value][data] to a TaskType. + /// + /// If [allowNull] is true and the [dynamic value][data] cannot be decoded successfully, + /// then null is returned. However, if [allowNull] is false and the [dynamic value][data] + /// cannot be decoded successfully, then an [UnimplementedError] is thrown. + /// + /// The [allowNull] is very handy when an API changes and a new enum value is added or removed, + /// and users are still using an old app with the old code. + TaskType? decode(dynamic data, {bool allowNull = true}) { + if (data != null) { + switch (data) { + case r'schedule': return TaskType.schedule; + case r'restore': return TaskType.restore; + case r'backup': return TaskType.backup; + case r'forget': return TaskType.forget; + default: + if (!allowNull) { + throw ArgumentError('Unknown enum value to decode: $data'); + } + } + } + return null; + } + + /// Singleton [TaskTypeTypeTransformer] instance. + static TaskTypeTypeTransformer? _instance; +} + diff --git a/open-api/immich-openapi-specs.json b/open-api/immich-openapi-specs.json index 8eb172c1fb..7f991a0eee 100644 --- a/open-api/immich-openapi-specs.json +++ b/open-api/immich-openapi-specs.json @@ -15153,6 +15153,965 @@ "x-immich-permission": "workflow.update", "x-immich-state": "Alpha" } + }, + "/yucca/auth/oidc/callback": { + "get": { + "operationId": "oidcCallback", + "parameters": [], + "responses": { + "200": { + "description": "" + } + }, + "tags": [ + "Auth" + ] + } + }, + "/yucca/auth/oidc/login": { + "get": { + "operationId": "oidcAuthorize", + "parameters": [ + { + "name": "next", + "required": true, + "in": "query", + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "" + } + }, + "tags": [ + "Auth" + ] + } + }, + "/yucca/backend": { + "get": { + "operationId": "getBackends", + "parameters": [], + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BackendsResponseDto" + } + } + }, + "description": "" + } + }, + "tags": [ + "Backend" + ] + } + }, + "/yucca/backend/local": { + "post": { + "operationId": "createLocalBackend", + "parameters": [], + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/CreateLocalBackendRequestDto" + } + } + }, + "required": true + }, + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BackendResponseDto" + } + } + }, + "description": "" + } + }, + "tags": [ + "Backend" + ] + } + }, + "/yucca/debug/reset": { + "post": { + "operationId": "resetOrchestrator", + "parameters": [], + "responses": { + "201": { + "description": "" + } + }, + "tags": [ + "Development" + ] + } + }, + "/yucca/fs": { + "get": { + "operationId": "getFileListing", + "parameters": [ + { + "name": "path", + "required": false, + "in": "query", + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/FilesystemListingResponseDto" + } + } + }, + "description": "" + } + }, + "tags": [ + "Filesystem" + ] + } + }, + "/yucca/integrations": { + "get": { + "operationId": "getIntegrations", + "parameters": [], + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/IntegrationsResponseDto" + } + } + }, + "description": "" + } + }, + "tags": [ + "Integrations" + ] + } + }, + "/yucca/integrations/immich": { + "post": { + "operationId": "configureImmichIntegration", + "parameters": [], + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ConfigureImmichIntegrationRequestDto" + } + } + }, + "required": true + }, + "responses": { + "201": { + "description": "" + } + }, + "tags": [ + "Integrations" + ] + } + }, + "/yucca/logs/{id}": { + "get": { + "operationId": "logStreamSse", + "parameters": [ + { + "name": "id", + "required": true, + "in": "path", + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "" + } + }, + "tags": [ + "RunHistory" + ] + } + }, + "/yucca/onboarding": { + "get": { + "operationId": "onboardingStatus", + "parameters": [], + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/OnboardingStatusResponseDto" + } + } + }, + "description": "" + } + }, + "tags": [ + "Onboarding" + ] + } + }, + "/yucca/onboarding/recovery-key": { + "get": { + "operationId": "currentRecoveryKey", + "parameters": [], + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/CurrentRecoveryKeyResponse" + } + } + }, + "description": "" + } + }, + "tags": [ + "Onboarding" + ] + }, + "post": { + "operationId": "confirmRecoveryKey", + "parameters": [], + "responses": { + "201": { + "description": "" + } + }, + "tags": [ + "Onboarding" + ] + }, + "put": { + "operationId": "importRecoveryKey", + "parameters": [], + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ImportRecoveryKeyRequest" + } + } + }, + "required": true + }, + "responses": { + "200": { + "description": "" + } + }, + "tags": [ + "Onboarding" + ] + } + }, + "/yucca/onboarding/skip": { + "post": { + "operationId": "skipOnboardingExtraConfig", + "parameters": [], + "responses": { + "201": { + "description": "" + } + }, + "tags": [ + "Onboarding" + ] + } + }, + "/yucca/repository": { + "get": { + "operationId": "getRepositories", + "parameters": [], + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/RepositoryListResponseDto" + } + } + }, + "description": "" + } + }, + "tags": [ + "Repository" + ] + }, + "post": { + "operationId": "createRepository", + "parameters": [ + { + "name": "backend", + "required": false, + "in": "query", + "schema": { + "type": "string" + } + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/RepositoryCreateRequestDto" + } + } + }, + "required": true + }, + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/RepositoryCreateResponseDto" + } + } + }, + "description": "" + } + }, + "tags": [ + "Repository" + ] + } + }, + "/yucca/repository/inspect": { + "get": { + "operationId": "inspectRepositories", + "parameters": [], + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/RepositoryInspectResponseDto" + } + } + }, + "description": "" + } + }, + "tags": [ + "Repository" + ] + } + }, + "/yucca/repository/{id}": { + "patch": { + "operationId": "updateRepository", + "parameters": [ + { + "name": "backend", + "required": false, + "in": "query", + "schema": { + "type": "string" + } + }, + { + "name": "id", + "required": true, + "in": "path", + "schema": { + "type": "string" + } + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/RepositoryUpdateRequestDto" + } + } + }, + "required": true + }, + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/RepositoryUpdateResponseDto" + } + } + }, + "description": "" + } + }, + "tags": [ + "Repository" + ] + }, + "post": { + "operationId": "createBackup", + "parameters": [ + { + "name": "id", + "required": true, + "in": "path", + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/LogResponseDto" + } + } + }, + "description": "" + } + }, + "tags": [ + "Repository" + ] + } + }, + "/yucca/repository/{id}/import": { + "get": { + "operationId": "checkImportRepository", + "parameters": [ + { + "name": "backend", + "required": true, + "in": "query", + "schema": { + "type": "string" + } + }, + { + "name": "id", + "required": true, + "in": "path", + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/RepositoryCheckImportResponseDto" + } + } + }, + "description": "" + } + }, + "tags": [ + "Repository" + ] + }, + "post": { + "operationId": "importRepository", + "parameters": [ + { + "name": "backend", + "required": true, + "in": "query", + "schema": { + "type": "string" + } + }, + { + "name": "id", + "required": true, + "in": "path", + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/RepositoryCreateResponseDto" + } + } + }, + "description": "" + } + }, + "tags": [ + "Repository" + ] + } + }, + "/yucca/repository/{id}/runs": { + "get": { + "operationId": "getRunHistory", + "parameters": [ + { + "name": "id", + "required": true, + "in": "path", + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/RunHistoryResponseDto" + } + } + }, + "description": "" + } + }, + "tags": [ + "Repository" + ] + } + }, + "/yucca/repository/{id}/snapshots": { + "get": { + "operationId": "getSnapshots", + "parameters": [ + { + "name": "id", + "required": true, + "in": "path", + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ListSnapshotsResponseDto" + } + } + }, + "description": "" + } + }, + "tags": [ + "Repository" + ] + } + }, + "/yucca/repository/{id}/snapshots/{snapshot}": { + "delete": { + "operationId": "forgetSnapshot", + "parameters": [ + { + "name": "id", + "required": true, + "in": "path", + "schema": { + "type": "string" + } + }, + { + "name": "snapshot", + "required": true, + "in": "path", + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ListSnapshotsResponseDto" + } + } + }, + "description": "" + } + }, + "tags": [ + "Repository" + ] + }, + "post": { + "operationId": "restoreSnapshot", + "parameters": [ + { + "name": "id", + "required": true, + "in": "path", + "schema": { + "type": "string" + } + }, + { + "name": "snapshot", + "required": true, + "in": "path", + "schema": { + "type": "string" + } + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/RepositorySnapshotRestoreRequestDto" + } + } + }, + "required": true + }, + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/LogResponseDto" + } + } + }, + "description": "" + } + }, + "tags": [ + "Repository" + ] + } + }, + "/yucca/repository/{id}/snapshots/{snapshot}/listing": { + "get": { + "operationId": "getSnapshotListing", + "parameters": [ + { + "name": "id", + "required": true, + "in": "path", + "schema": { + "type": "string" + } + }, + { + "name": "path", + "required": false, + "in": "query", + "schema": { + "type": "string" + } + }, + { + "name": "snapshot", + "required": true, + "in": "path", + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/FilesystemListingResponseDto" + } + } + }, + "description": "" + } + }, + "tags": [ + "Repository" + ] + } + }, + "/yucca/repository/{id}/snapshots/{snapshot}/restore-from-point": { + "post": { + "operationId": "restoreFromPoint", + "parameters": [ + { + "name": "backend", + "required": true, + "in": "query", + "schema": { + "type": "string" + } + }, + { + "name": "id", + "required": true, + "in": "path", + "schema": { + "type": "string" + } + }, + { + "name": "snapshot", + "required": true, + "in": "path", + "schema": { + "type": "string" + } + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/RepositorySnapshotRestoreFromPointRequestDto" + } + } + }, + "required": true + }, + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/LogResponseDto" + } + } + }, + "description": "" + } + }, + "tags": [ + "Repository" + ] + } + }, + "/yucca/schedule": { + "get": { + "operationId": "getSchedules", + "parameters": [], + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ScheduleListResponseDto" + } + } + }, + "description": "" + } + }, + "tags": [ + "Schedule" + ] + }, + "post": { + "operationId": "createSchedule", + "parameters": [], + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ScheduleCreateRequestDto" + } + } + }, + "required": true + }, + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ScheduleCreateResponseDto" + } + } + }, + "description": "" + } + }, + "tags": [ + "Schedule" + ] + } + }, + "/yucca/schedule/{id}": { + "delete": { + "operationId": "removeSchedule", + "parameters": [ + { + "name": "id", + "required": true, + "in": "path", + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "" + } + }, + "tags": [ + "Schedule" + ] + }, + "patch": { + "operationId": "updateSchedule", + "parameters": [ + { + "name": "id", + "required": true, + "in": "path", + "schema": { + "type": "string" + } + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ScheduleUpdateRequestDto" + } + } + }, + "required": true + }, + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ScheduleUpdateResponseDto" + } + } + }, + "description": "" + } + }, + "tags": [ + "Schedule" + ] + } + }, + "/yucca/schedule/{id}/{repositoryId}": { + "delete": { + "operationId": "removeRepositoryFromSchedule", + "parameters": [ + { + "name": "id", + "required": true, + "in": "path", + "schema": { + "type": "string" + } + }, + { + "name": "repositoryId", + "required": true, + "in": "path", + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "" + } + }, + "tags": [ + "Schedule" + ] + }, + "put": { + "operationId": "addRepositoryToSchedule", + "parameters": [ + { + "name": "id", + "required": true, + "in": "path", + "schema": { + "type": "string" + } + }, + { + "name": "repositoryId", + "required": true, + "in": "path", + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "" + } + }, + "tags": [ + "Schedule" + ] + } + }, + "/yucca/tasks": { + "get": { + "operationId": "getRunningTasks", + "parameters": [], + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/RunningTaskListResponse" + } + } + }, + "description": "" + } + }, + "tags": [ + "RunningTasks" + ] + } } }, "info": { @@ -15430,6 +16389,25 @@ }, "type": "object" }, + "ActiveScheduleItemDto": { + "properties": { + "repositoryId": { + "type": "string" + }, + "status": { + "allOf": [ + { + "$ref": "#/components/schemas/TaskStatus" + } + ] + } + }, + "required": [ + "repositoryId", + "status" + ], + "type": "object" + }, "ActivityCreateDto": { "description": "Activity create", "properties": { @@ -17265,6 +18243,65 @@ }, "type": "object" }, + "BackendDto": { + "properties": { + "error": { + "type": "string" + }, + "id": { + "type": "string" + }, + "isOnline": { + "type": "boolean" + }, + "type": { + "allOf": [ + { + "$ref": "#/components/schemas/BackendType" + } + ] + } + }, + "required": [ + "id", + "isOnline", + "type" + ], + "type": "object" + }, + "BackendResponseDto": { + "properties": { + "backend": { + "$ref": "#/components/schemas/BackendDto" + } + }, + "required": [ + "backend" + ], + "type": "object" + }, + "BackendType": { + "enum": [ + "yucca", + "local", + "s3" + ], + "type": "string" + }, + "BackendsResponseDto": { + "properties": { + "backends": { + "items": { + "$ref": "#/components/schemas/BackendDto" + }, + "type": "array" + } + }, + "required": [ + "backends" + ], + "type": "object" + }, "BulkIdErrorReason": { "description": "Error reason", "enum": [ @@ -17432,6 +18469,53 @@ ], "type": "string" }, + "ConfigureImmichIntegrationRequestDto": { + "properties": { + "backupConfiguration": { + "type": "boolean" + }, + "cron": { + "type": "string" + }, + "dataFolders": { + "items": { + "type": "string" + }, + "type": "array" + }, + "libraries": { + "oneOf": [ + { + "type": "string", + "enum": [ + "all" + ] + }, + { + "type": "array", + "items": { + "type": "string" + } + } + ] + }, + "name": { + "type": "string" + }, + "worm": { + "type": "boolean" + } + }, + "required": [ + "backupConfiguration", + "cron", + "dataFolders", + "libraries", + "name", + "worm" + ], + "type": "object" + }, "ContributorCountResponseDto": { "properties": { "assetCount": { @@ -17518,6 +18602,17 @@ ], "type": "object" }, + "CreateLocalBackendRequestDto": { + "properties": { + "path": { + "type": "string" + } + }, + "required": [ + "path" + ], + "type": "object" + }, "CreateProfileImageDto": { "properties": { "file": { @@ -17587,6 +18682,17 @@ ], "type": "object" }, + "CurrentRecoveryKeyResponse": { + "properties": { + "recoveryKey": { + "type": "string" + } + }, + "required": [ + "recoveryKey" + ], + "type": "object" + }, "DatabaseBackupConfig": { "properties": { "cronExpression": { @@ -18140,6 +19246,43 @@ ], "type": "object" }, + "FilesystemListingItemDto": { + "properties": { + "isDirectory": { + "type": "boolean" + }, + "path": { + "type": "string" + } + }, + "required": [ + "isDirectory", + "path" + ], + "type": "object" + }, + "FilesystemListingResponseDto": { + "properties": { + "items": { + "items": { + "$ref": "#/components/schemas/FilesystemListingItemDto" + }, + "type": "array" + }, + "parent": { + "type": "string" + }, + "path": { + "type": "string" + } + }, + "required": [ + "items", + "parent", + "path" + ], + "type": "object" + }, "FoldersResponse": { "properties": { "enabled": { @@ -18178,6 +19321,172 @@ ], "type": "string" }, + "ImmichIntegrationConfigurationDto": { + "properties": { + "backupConfiguration": { + "type": "boolean" + }, + "dataFolders": { + "items": { + "type": "string" + }, + "type": "array" + }, + "libraries": { + "oneOf": [ + { + "type": "string", + "enum": [ + "all" + ] + }, + { + "type": "array", + "items": { + "type": "string" + } + } + ] + } + }, + "required": [ + "backupConfiguration", + "dataFolders", + "libraries" + ], + "type": "object" + }, + "ImmichIntegrationDto": { + "properties": { + "configuration": { + "$ref": "#/components/schemas/ImmichIntegrationConfigurationDto" + }, + "id": { + "type": "string" + }, + "scheduleId": { + "type": "string" + } + }, + "required": [ + "configuration", + "id", + "scheduleId" + ], + "type": "object" + }, + "ImmichLibraryDto": { + "properties": { + "exclusionPatterns": { + "items": { + "type": "string" + }, + "type": "array" + }, + "id": { + "type": "string" + }, + "importPaths": { + "items": { + "type": "string" + }, + "type": "array" + }, + "name": { + "type": "string" + } + }, + "required": [ + "exclusionPatterns", + "id", + "importPaths", + "name" + ], + "type": "object" + }, + "ImmichStateDto": { + "properties": { + "dataFolders": { + "items": { + "type": "string" + }, + "type": "array" + }, + "dataPath": { + "type": "string" + }, + "libraries": { + "items": { + "$ref": "#/components/schemas/ImmichLibraryDto" + }, + "type": "array" + } + }, + "required": [ + "dataFolders", + "dataPath", + "libraries" + ], + "type": "object" + }, + "ImportRecoveryKeyRequest": { + "properties": { + "recoveryKey": { + "type": "string" + } + }, + "required": [ + "recoveryKey" + ], + "type": "object" + }, + "InspectedLocalRepositoryDto": { + "properties": { + "backends": { + "$ref": "#/components/schemas/RepositoryBackendsDto" + }, + "configuration": { + "$ref": "#/components/schemas/RepositoryConfigurationDto" + }, + "id": { + "type": "string" + }, + "metrics": { + "$ref": "#/components/schemas/RepositoryMetricsDto" + }, + "name": { + "type": "string" + }, + "snapshots": { + "items": { + "$ref": "#/components/schemas/SnapshotDto" + }, + "type": "array" + }, + "worm": { + "type": "boolean" + } + }, + "required": [ + "id", + "metrics", + "name", + "snapshots", + "worm" + ], + "type": "object" + }, + "IntegrationsResponseDto": { + "properties": { + "immichIntegration": { + "$ref": "#/components/schemas/ImmichIntegrationDto" + }, + "immichState": { + "$ref": "#/components/schemas/ImmichStateDto" + } + }, + "type": "object" + }, "JobCreateDto": { "properties": { "name": { @@ -18391,6 +19700,49 @@ "LicenseResponseDto": { "$ref": "#/components/schemas/UserLicense" }, + "ListSnapshotsResponseDto": { + "properties": { + "snapshots": { + "items": { + "$ref": "#/components/schemas/SnapshotDto" + }, + "type": "array" + } + }, + "required": [ + "snapshots" + ], + "type": "object" + }, + "LocalRepositoryDto": { + "properties": { + "backends": { + "$ref": "#/components/schemas/RepositoryBackendsDto" + }, + "configuration": { + "$ref": "#/components/schemas/RepositoryConfigurationDto" + }, + "id": { + "type": "string" + }, + "metrics": { + "$ref": "#/components/schemas/RepositoryMetricsDto" + }, + "name": { + "type": "string" + }, + "worm": { + "type": "boolean" + } + }, + "required": [ + "id", + "metrics", + "name", + "worm" + ], + "type": "object" + }, "LogLevel": { "description": "Log level", "enum": [ @@ -18403,6 +19755,17 @@ ], "type": "string" }, + "LogResponseDto": { + "properties": { + "logId": { + "type": "string" + } + }, + "required": [ + "logId" + ], + "type": "object" + }, "LoginCredentialDto": { "properties": { "email": { @@ -19538,6 +20901,33 @@ ], "type": "object" }, + "OnboardingStatusResponseDto": { + "properties": { + "hasBackend": { + "type": "boolean" + }, + "hasBackup": { + "type": "boolean" + }, + "hasOnboardedKey": { + "type": "boolean" + }, + "hasSchedule": { + "type": "boolean" + }, + "hasSkippedExtraConfig": { + "type": "boolean" + } + }, + "required": [ + "hasBackend", + "hasBackup", + "hasOnboardedKey", + "hasSchedule", + "hasSkippedExtraConfig" + ], + "type": "object" + }, "PartnerCreateDto": { "properties": { "sharedWithId": { @@ -21087,6 +22477,205 @@ ], "type": "string" }, + "RepositoryBackendDto": { + "properties": { + "id": { + "type": "string" + }, + "online": { + "type": "boolean" + }, + "type": { + "allOf": [ + { + "$ref": "#/components/schemas/BackendType" + } + ] + } + }, + "required": [ + "id", + "online", + "type" + ], + "type": "object" + }, + "RepositoryBackendsDto": { + "properties": { + "primary": { + "$ref": "#/components/schemas/RepositoryBackendDto" + }, + "secondary": { + "items": { + "$ref": "#/components/schemas/RepositoryBackendDto" + }, + "type": "array" + } + }, + "required": [ + "primary", + "secondary" + ], + "type": "object" + }, + "RepositoryCheckImportResponseDto": { + "properties": { + "readable": { + "type": "boolean" + } + }, + "required": [ + "readable" + ], + "type": "object" + }, + "RepositoryConfigurationDto": { + "properties": { + "paths": { + "items": { + "type": "string" + }, + "type": "array" + } + }, + "required": [ + "paths" + ], + "type": "object" + }, + "RepositoryCreateRequestDto": { + "properties": { + "name": { + "type": "string" + }, + "paths": { + "items": { + "type": "string" + }, + "type": "array" + }, + "worm": { + "type": "boolean" + } + }, + "required": [ + "name", + "worm" + ], + "type": "object" + }, + "RepositoryCreateResponseDto": { + "properties": { + "repository": { + "$ref": "#/components/schemas/LocalRepositoryDto" + } + }, + "required": [ + "repository" + ], + "type": "object" + }, + "RepositoryInspectResponseDto": { + "properties": { + "repositories": { + "items": { + "$ref": "#/components/schemas/InspectedLocalRepositoryDto" + }, + "type": "array" + } + }, + "required": [ + "repositories" + ], + "type": "object" + }, + "RepositoryListResponseDto": { + "properties": { + "repositories": { + "items": { + "$ref": "#/components/schemas/LocalRepositoryDto" + }, + "type": "array" + } + }, + "required": [ + "repositories" + ], + "type": "object" + }, + "RepositoryMetricsDto": { + "properties": { + "lastBackup": { + "type": "string" + }, + "lastBackupDuration": { + "type": "number" + }, + "lastSuccessfulBackup": { + "type": "string" + }, + "sizeBytes": { + "type": "number" + } + }, + "required": [ + "sizeBytes" + ], + "type": "object" + }, + "RepositorySnapshotRestoreFromPointRequestDto": { + "properties": { + "include": { + "items": { + "type": "string" + }, + "type": "array" + }, + "yuccaConfig": { + "type": "string" + } + }, + "type": "object" + }, + "RepositorySnapshotRestoreRequestDto": { + "properties": { + "include": { + "items": { + "type": "string" + }, + "type": "array" + }, + "target": { + "type": "string" + } + }, + "type": "object" + }, + "RepositoryUpdateRequestDto": { + "properties": { + "name": { + "type": "string" + }, + "paths": { + "items": { + "type": "string" + }, + "type": "array" + } + }, + "type": "object" + }, + "RepositoryUpdateResponseDto": { + "properties": { + "repository": { + "$ref": "#/components/schemas/LocalRepositoryDto" + } + }, + "required": [ + "repository" + ], + "type": "object" + }, "ReverseGeocodingStateResponseDto": { "properties": { "lastImportFileName": { @@ -21118,6 +22707,215 @@ ], "type": "object" }, + "RunDto": { + "properties": { + "end": { + "type": "string" + }, + "id": { + "type": "string" + }, + "logFilePath": { + "type": "string" + }, + "start": { + "type": "string" + }, + "status": { + "allOf": [ + { + "$ref": "#/components/schemas/RunStatus" + } + ] + } + }, + "required": [ + "end", + "id", + "logFilePath", + "start", + "status" + ], + "type": "object" + }, + "RunHistoryResponseDto": { + "properties": { + "runs": { + "items": { + "$ref": "#/components/schemas/RunDto" + }, + "type": "array" + } + }, + "required": [ + "runs" + ], + "type": "object" + }, + "RunStatus": { + "enum": [ + "incomplete", + "complete", + "failed" + ], + "type": "string" + }, + "RunningTaskDto": { + "properties": { + "logId": { + "type": "string" + }, + "parentId": { + "type": "string" + }, + "scheduleStatus": { + "items": { + "$ref": "#/components/schemas/ActiveScheduleItemDto" + }, + "type": "array" + }, + "type": { + "allOf": [ + { + "$ref": "#/components/schemas/TaskType" + } + ] + } + }, + "required": [ + "parentId", + "type" + ], + "type": "object" + }, + "RunningTaskListResponse": { + "properties": { + "tasks": { + "items": { + "$ref": "#/components/schemas/RunningTaskDto" + }, + "type": "array" + } + }, + "required": [ + "tasks" + ], + "type": "object" + }, + "ScheduleCreateRequestDto": { + "properties": { + "cron": { + "type": "string" + }, + "name": { + "type": "string" + }, + "repositories": { + "items": { + "type": "string" + }, + "type": "array" + } + }, + "required": [ + "cron", + "name", + "repositories" + ], + "type": "object" + }, + "ScheduleCreateResponseDto": { + "properties": { + "schedule": { + "$ref": "#/components/schemas/ScheduleDto" + } + }, + "required": [ + "schedule" + ], + "type": "object" + }, + "ScheduleDto": { + "properties": { + "cron": { + "type": "string" + }, + "id": { + "type": "string" + }, + "lastFinished": { + "type": "string" + }, + "lastRun": { + "type": "string" + }, + "name": { + "type": "string" + }, + "paused": { + "type": "boolean" + }, + "repositories": { + "items": { + "type": "string" + }, + "type": "array" + } + }, + "required": [ + "cron", + "id", + "name", + "paused", + "repositories" + ], + "type": "object" + }, + "ScheduleListResponseDto": { + "properties": { + "schedules": { + "items": { + "$ref": "#/components/schemas/ScheduleDto" + }, + "type": "array" + } + }, + "required": [ + "schedules" + ], + "type": "object" + }, + "ScheduleUpdateRequestDto": { + "properties": { + "cron": { + "type": "string" + }, + "name": { + "type": "string" + }, + "paused": { + "type": "boolean" + }, + "repositories": { + "items": { + "type": "string" + }, + "type": "array" + } + }, + "type": "object" + }, + "ScheduleUpdateResponseDto": { + "properties": { + "schedule": { + "$ref": "#/components/schemas/ScheduleDto" + } + }, + "required": [ + "schedule" + ], + "type": "object" + }, "SearchAlbumResponseDto": { "properties": { "count": { @@ -22440,6 +24238,28 @@ }, "type": "object" }, + "SnapshotDto": { + "properties": { + "id": { + "type": "string" + }, + "paths": { + "items": { + "type": "string" + }, + "type": "array" + }, + "time": { + "type": "string" + } + }, + "required": [ + "id", + "paths", + "time" + ], + "type": "object" + }, "SourceType": { "description": "Face detection source type", "enum": [ @@ -25201,6 +27021,23 @@ }, "type": "object" }, + "TaskStatus": { + "enum": [ + "incomplete", + "complete", + "failed" + ], + "type": "string" + }, + "TaskType": { + "enum": [ + "schedule", + "restore", + "backup", + "forget" + ], + "type": "string" + }, "TemplateDto": { "properties": { "template": { diff --git a/open-api/typescript-sdk/src/fetch-client.ts b/open-api/typescript-sdk/src/fetch-client.ts index de6e2383e9..4ad7efda7d 100644 --- a/open-api/typescript-sdk/src/fetch-client.ts +++ b/open-api/typescript-sdk/src/fetch-client.ts @@ -2877,6 +2877,206 @@ export type WorkflowUpdateDto = { name?: string; triggerType?: PluginTriggerType; }; +export type BackendDto = { + error?: string; + id: string; + isOnline: boolean; + "type": BackendType; +}; +export type BackendsResponseDto = { + backends: BackendDto[]; +}; +export type CreateLocalBackendRequestDto = { + path: string; +}; +export type BackendResponseDto = { + backend: BackendDto; +}; +export type FilesystemListingItemDto = { + isDirectory: boolean; + path: string; +}; +export type FilesystemListingResponseDto = { + items: FilesystemListingItemDto[]; + parent: string; + path: string; +}; +export type ImmichIntegrationConfigurationDto = { + backupConfiguration: boolean; + dataFolders: string[]; + libraries: "all" | string[]; +}; +export type ImmichIntegrationDto = { + configuration: ImmichIntegrationConfigurationDto; + id: string; + scheduleId: string; +}; +export type ImmichLibraryDto = { + exclusionPatterns: string[]; + id: string; + importPaths: string[]; + name: string; +}; +export type ImmichStateDto = { + dataFolders: string[]; + dataPath: string; + libraries: ImmichLibraryDto[]; +}; +export type IntegrationsResponseDto = { + immichIntegration?: ImmichIntegrationDto; + immichState?: ImmichStateDto; +}; +export type ConfigureImmichIntegrationRequestDto = { + backupConfiguration: boolean; + cron: string; + dataFolders: string[]; + libraries: "all" | string[]; + name: string; + worm: boolean; +}; +export type OnboardingStatusResponseDto = { + hasBackend: boolean; + hasBackup: boolean; + hasOnboardedKey: boolean; + hasSchedule: boolean; + hasSkippedExtraConfig: boolean; +}; +export type CurrentRecoveryKeyResponse = { + recoveryKey: string; +}; +export type ImportRecoveryKeyRequest = { + recoveryKey: string; +}; +export type RepositoryBackendDto = { + id: string; + online: boolean; + "type": BackendType; +}; +export type RepositoryBackendsDto = { + primary: RepositoryBackendDto; + secondary: RepositoryBackendDto[]; +}; +export type RepositoryConfigurationDto = { + paths: string[]; +}; +export type RepositoryMetricsDto = { + lastBackup?: string; + lastBackupDuration?: number; + lastSuccessfulBackup?: string; + sizeBytes: number; +}; +export type LocalRepositoryDto = { + backends?: RepositoryBackendsDto; + configuration?: RepositoryConfigurationDto; + id: string; + metrics: RepositoryMetricsDto; + name: string; + worm: boolean; +}; +export type RepositoryListResponseDto = { + repositories: LocalRepositoryDto[]; +}; +export type RepositoryCreateRequestDto = { + name: string; + paths?: string[]; + worm: boolean; +}; +export type RepositoryCreateResponseDto = { + repository: LocalRepositoryDto; +}; +export type SnapshotDto = { + id: string; + paths: string[]; + time: string; +}; +export type InspectedLocalRepositoryDto = { + backends?: RepositoryBackendsDto; + configuration?: RepositoryConfigurationDto; + id: string; + metrics: RepositoryMetricsDto; + name: string; + snapshots: SnapshotDto[]; + worm: boolean; +}; +export type RepositoryInspectResponseDto = { + repositories: InspectedLocalRepositoryDto[]; +}; +export type RepositoryUpdateRequestDto = { + name?: string; + paths?: string[]; +}; +export type RepositoryUpdateResponseDto = { + repository: LocalRepositoryDto; +}; +export type LogResponseDto = { + logId: string; +}; +export type RepositoryCheckImportResponseDto = { + readable: boolean; +}; +export type RunDto = { + end: string; + id: string; + logFilePath: string; + start: string; + status: RunStatus; +}; +export type RunHistoryResponseDto = { + runs: RunDto[]; +}; +export type ListSnapshotsResponseDto = { + snapshots: SnapshotDto[]; +}; +export type RepositorySnapshotRestoreRequestDto = { + include?: string[]; + target?: string; +}; +export type RepositorySnapshotRestoreFromPointRequestDto = { + include?: string[]; + yuccaConfig?: string; +}; +export type ScheduleDto = { + cron: string; + id: string; + lastFinished?: string; + lastRun?: string; + name: string; + paused: boolean; + repositories: string[]; +}; +export type ScheduleListResponseDto = { + schedules: ScheduleDto[]; +}; +export type ScheduleCreateRequestDto = { + cron: string; + name: string; + repositories: string[]; +}; +export type ScheduleCreateResponseDto = { + schedule: ScheduleDto; +}; +export type ScheduleUpdateRequestDto = { + cron?: string; + name?: string; + paused?: boolean; + repositories?: string[]; +}; +export type ScheduleUpdateResponseDto = { + schedule: ScheduleDto; +}; +export type ActiveScheduleItemDto = { + repositoryId: string; + status: TaskStatus; +}; +export type RunningTaskDto = { + logId?: string; + parentId: string; + scheduleStatus?: ActiveScheduleItemDto[]; + "type": TaskType; +}; +export type RunningTaskListResponse = { + tasks: RunningTaskDto[]; +}; export type LicenseResponseDto = UserLicense; export type SyncAckV1 = {}; export type SyncAlbumDeleteV1 = { @@ -6755,6 +6955,348 @@ export function updateWorkflow({ id, workflowUpdateDto }: { body: workflowUpdateDto }))); } +export function oidcCallback(opts?: Oazapfts.RequestOpts) { + return oazapfts.ok(oazapfts.fetchText("/yucca/auth/oidc/callback", { + ...opts + })); +} +export function oidcAuthorize({ next }: { + next: string; +}, opts?: Oazapfts.RequestOpts) { + return oazapfts.ok(oazapfts.fetchText(`/yucca/auth/oidc/login${QS.query(QS.explode({ + next + }))}`, { + ...opts + })); +} +export function getBackends(opts?: Oazapfts.RequestOpts) { + return oazapfts.ok(oazapfts.fetchJson<{ + status: 200; + data: BackendsResponseDto; + }>("/yucca/backend", { + ...opts + })); +} +export function createLocalBackend({ createLocalBackendRequestDto }: { + createLocalBackendRequestDto: CreateLocalBackendRequestDto; +}, opts?: Oazapfts.RequestOpts) { + return oazapfts.ok(oazapfts.fetchJson<{ + status: 200; + data: BackendResponseDto; + }>("/yucca/backend/local", oazapfts.json({ + ...opts, + method: "POST", + body: createLocalBackendRequestDto + }))); +} +export function resetOrchestrator(opts?: Oazapfts.RequestOpts) { + return oazapfts.ok(oazapfts.fetchText("/yucca/debug/reset", { + ...opts, + method: "POST" + })); +} +export function getFileListing({ path }: { + path?: string; +}, opts?: Oazapfts.RequestOpts) { + return oazapfts.ok(oazapfts.fetchJson<{ + status: 200; + data: FilesystemListingResponseDto; + }>(`/yucca/fs${QS.query(QS.explode({ + path + }))}`, { + ...opts + })); +} +export function getIntegrations(opts?: Oazapfts.RequestOpts) { + return oazapfts.ok(oazapfts.fetchJson<{ + status: 200; + data: IntegrationsResponseDto; + }>("/yucca/integrations", { + ...opts + })); +} +export function configureImmichIntegration({ configureImmichIntegrationRequestDto }: { + configureImmichIntegrationRequestDto: ConfigureImmichIntegrationRequestDto; +}, opts?: Oazapfts.RequestOpts) { + return oazapfts.ok(oazapfts.fetchText("/yucca/integrations/immich", oazapfts.json({ + ...opts, + method: "POST", + body: configureImmichIntegrationRequestDto + }))); +} +export function logStreamSse({ id }: { + id: string; +}, opts?: Oazapfts.RequestOpts) { + return oazapfts.ok(oazapfts.fetchText(`/yucca/logs/${encodeURIComponent(id)}`, { + ...opts + })); +} +export function onboardingStatus(opts?: Oazapfts.RequestOpts) { + return oazapfts.ok(oazapfts.fetchJson<{ + status: 200; + data: OnboardingStatusResponseDto; + }>("/yucca/onboarding", { + ...opts + })); +} +export function currentRecoveryKey(opts?: Oazapfts.RequestOpts) { + return oazapfts.ok(oazapfts.fetchJson<{ + status: 200; + data: CurrentRecoveryKeyResponse; + }>("/yucca/onboarding/recovery-key", { + ...opts + })); +} +export function confirmRecoveryKey(opts?: Oazapfts.RequestOpts) { + return oazapfts.ok(oazapfts.fetchText("/yucca/onboarding/recovery-key", { + ...opts, + method: "POST" + })); +} +export function importRecoveryKey({ importRecoveryKeyRequest }: { + importRecoveryKeyRequest: ImportRecoveryKeyRequest; +}, opts?: Oazapfts.RequestOpts) { + return oazapfts.ok(oazapfts.fetchText("/yucca/onboarding/recovery-key", oazapfts.json({ + ...opts, + method: "PUT", + body: importRecoveryKeyRequest + }))); +} +export function skipOnboardingExtraConfig(opts?: Oazapfts.RequestOpts) { + return oazapfts.ok(oazapfts.fetchText("/yucca/onboarding/skip", { + ...opts, + method: "POST" + })); +} +export function getRepositories(opts?: Oazapfts.RequestOpts) { + return oazapfts.ok(oazapfts.fetchJson<{ + status: 200; + data: RepositoryListResponseDto; + }>("/yucca/repository", { + ...opts + })); +} +export function createRepository({ backend, repositoryCreateRequestDto }: { + backend?: string; + repositoryCreateRequestDto: RepositoryCreateRequestDto; +}, opts?: Oazapfts.RequestOpts) { + return oazapfts.ok(oazapfts.fetchJson<{ + status: 200; + data: RepositoryCreateResponseDto; + }>(`/yucca/repository${QS.query(QS.explode({ + backend + }))}`, oazapfts.json({ + ...opts, + method: "POST", + body: repositoryCreateRequestDto + }))); +} +export function inspectRepositories(opts?: Oazapfts.RequestOpts) { + return oazapfts.ok(oazapfts.fetchJson<{ + status: 200; + data: RepositoryInspectResponseDto; + }>("/yucca/repository/inspect", { + ...opts + })); +} +export function updateRepository({ backend, id, repositoryUpdateRequestDto }: { + backend?: string; + id: string; + repositoryUpdateRequestDto: RepositoryUpdateRequestDto; +}, opts?: Oazapfts.RequestOpts) { + return oazapfts.ok(oazapfts.fetchJson<{ + status: 200; + data: RepositoryUpdateResponseDto; + }>(`/yucca/repository/${encodeURIComponent(id)}${QS.query(QS.explode({ + backend + }))}`, oazapfts.json({ + ...opts, + method: "PATCH", + body: repositoryUpdateRequestDto + }))); +} +export function createBackup({ id }: { + id: string; +}, opts?: Oazapfts.RequestOpts) { + return oazapfts.ok(oazapfts.fetchJson<{ + status: 200; + data: LogResponseDto; + }>(`/yucca/repository/${encodeURIComponent(id)}`, { + ...opts, + method: "POST" + })); +} +export function checkImportRepository({ backend, id }: { + backend: string; + id: string; +}, opts?: Oazapfts.RequestOpts) { + return oazapfts.ok(oazapfts.fetchJson<{ + status: 200; + data: RepositoryCheckImportResponseDto; + }>(`/yucca/repository/${encodeURIComponent(id)}/import${QS.query(QS.explode({ + backend + }))}`, { + ...opts + })); +} +export function importRepository({ backend, id }: { + backend: string; + id: string; +}, opts?: Oazapfts.RequestOpts) { + return oazapfts.ok(oazapfts.fetchJson<{ + status: 200; + data: RepositoryCreateResponseDto; + }>(`/yucca/repository/${encodeURIComponent(id)}/import${QS.query(QS.explode({ + backend + }))}`, { + ...opts, + method: "POST" + })); +} +export function getRunHistory({ id }: { + id: string; +}, opts?: Oazapfts.RequestOpts) { + return oazapfts.ok(oazapfts.fetchJson<{ + status: 200; + data: RunHistoryResponseDto; + }>(`/yucca/repository/${encodeURIComponent(id)}/runs`, { + ...opts + })); +} +export function getSnapshots({ id }: { + id: string; +}, opts?: Oazapfts.RequestOpts) { + return oazapfts.ok(oazapfts.fetchJson<{ + status: 200; + data: ListSnapshotsResponseDto; + }>(`/yucca/repository/${encodeURIComponent(id)}/snapshots`, { + ...opts + })); +} +export function forgetSnapshot({ id, snapshot }: { + id: string; + snapshot: string; +}, opts?: Oazapfts.RequestOpts) { + return oazapfts.ok(oazapfts.fetchJson<{ + status: 200; + data: ListSnapshotsResponseDto; + }>(`/yucca/repository/${encodeURIComponent(id)}/snapshots/${encodeURIComponent(snapshot)}`, { + ...opts, + method: "DELETE" + })); +} +export function restoreSnapshot({ id, snapshot, repositorySnapshotRestoreRequestDto }: { + id: string; + snapshot: string; + repositorySnapshotRestoreRequestDto: RepositorySnapshotRestoreRequestDto; +}, opts?: Oazapfts.RequestOpts) { + return oazapfts.ok(oazapfts.fetchJson<{ + status: 200; + data: LogResponseDto; + }>(`/yucca/repository/${encodeURIComponent(id)}/snapshots/${encodeURIComponent(snapshot)}`, oazapfts.json({ + ...opts, + method: "POST", + body: repositorySnapshotRestoreRequestDto + }))); +} +export function getSnapshotListing({ id, path, snapshot }: { + id: string; + path?: string; + snapshot: string; +}, opts?: Oazapfts.RequestOpts) { + return oazapfts.ok(oazapfts.fetchJson<{ + status: 200; + data: FilesystemListingResponseDto; + }>(`/yucca/repository/${encodeURIComponent(id)}/snapshots/${encodeURIComponent(snapshot)}/listing${QS.query(QS.explode({ + path + }))}`, { + ...opts + })); +} +export function restoreFromPoint({ backend, id, snapshot, repositorySnapshotRestoreFromPointRequestDto }: { + backend: string; + id: string; + snapshot: string; + repositorySnapshotRestoreFromPointRequestDto: RepositorySnapshotRestoreFromPointRequestDto; +}, opts?: Oazapfts.RequestOpts) { + return oazapfts.ok(oazapfts.fetchJson<{ + status: 200; + data: LogResponseDto; + }>(`/yucca/repository/${encodeURIComponent(id)}/snapshots/${encodeURIComponent(snapshot)}/restore-from-point${QS.query(QS.explode({ + backend + }))}`, oazapfts.json({ + ...opts, + method: "POST", + body: repositorySnapshotRestoreFromPointRequestDto + }))); +} +export function getSchedules(opts?: Oazapfts.RequestOpts) { + return oazapfts.ok(oazapfts.fetchJson<{ + status: 200; + data: ScheduleListResponseDto; + }>("/yucca/schedule", { + ...opts + })); +} +export function createSchedule({ scheduleCreateRequestDto }: { + scheduleCreateRequestDto: ScheduleCreateRequestDto; +}, opts?: Oazapfts.RequestOpts) { + return oazapfts.ok(oazapfts.fetchJson<{ + status: 200; + data: ScheduleCreateResponseDto; + }>("/yucca/schedule", oazapfts.json({ + ...opts, + method: "POST", + body: scheduleCreateRequestDto + }))); +} +export function removeSchedule({ id }: { + id: string; +}, opts?: Oazapfts.RequestOpts) { + return oazapfts.ok(oazapfts.fetchText(`/yucca/schedule/${encodeURIComponent(id)}`, { + ...opts, + method: "DELETE" + })); +} +export function updateSchedule({ id, scheduleUpdateRequestDto }: { + id: string; + scheduleUpdateRequestDto: ScheduleUpdateRequestDto; +}, opts?: Oazapfts.RequestOpts) { + return oazapfts.ok(oazapfts.fetchJson<{ + status: 200; + data: ScheduleUpdateResponseDto; + }>(`/yucca/schedule/${encodeURIComponent(id)}`, oazapfts.json({ + ...opts, + method: "PATCH", + body: scheduleUpdateRequestDto + }))); +} +export function removeRepositoryFromSchedule({ id, repositoryId }: { + id: string; + repositoryId: string; +}, opts?: Oazapfts.RequestOpts) { + return oazapfts.ok(oazapfts.fetchText(`/yucca/schedule/${encodeURIComponent(id)}/${encodeURIComponent(repositoryId)}`, { + ...opts, + method: "DELETE" + })); +} +export function addRepositoryToSchedule({ id, repositoryId }: { + id: string; + repositoryId: string; +}, opts?: Oazapfts.RequestOpts) { + return oazapfts.ok(oazapfts.fetchText(`/yucca/schedule/${encodeURIComponent(id)}/${encodeURIComponent(repositoryId)}`, { + ...opts, + method: "PUT" + })); +} +export function getRunningTasks(opts?: Oazapfts.RequestOpts) { + return oazapfts.ok(oazapfts.fetchJson<{ + status: 200; + data: RunningTaskListResponse; + }>("/yucca/tasks", { + ...opts + })); +} export enum ReactionLevel { Album = "album", Asset = "asset" @@ -7319,6 +7861,27 @@ export enum OAuthTokenEndpointAuthMethod { ClientSecretPost = "client_secret_post", ClientSecretBasic = "client_secret_basic" } +export enum BackendType { + Yucca = "yucca", + Local = "local", + S3 = "s3" +} +export enum RunStatus { + Incomplete = "incomplete", + Complete = "complete", + Failed = "failed" +} +export enum TaskStatus { + Incomplete = "incomplete", + Complete = "complete", + Failed = "failed" +} +export enum TaskType { + Schedule = "schedule", + Restore = "restore", + Backup = "backup", + Forget = "forget" +} export enum UserMetadataKey { Preferences = "preferences", License = "license", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 077f7a6785..ed87cfd2f6 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -252,6 +252,9 @@ importers: luxon: specifier: ^3.4.4 version: 3.7.2 + orchestration-ui: + specifier: 0.1.54 + version: 0.1.54(svelte@5.55.1) pg: specifier: ^8.11.3 version: 8.20.0 @@ -348,28 +351,28 @@ importers: version: 0.3.2 '@nestjs/bullmq': specifier: ^11.0.1 - version: 11.0.4(@nestjs/common@11.1.17(class-transformer@0.5.1)(class-validator@0.15.1)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.18)(bullmq@5.71.0) + version: 11.0.4(@nestjs/common@11.1.17(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.18)(bullmq@5.71.0) '@nestjs/common': specifier: ^11.0.4 - version: 11.1.17(class-transformer@0.5.1)(class-validator@0.15.1)(reflect-metadata@0.2.2)(rxjs@7.8.2) + version: 11.1.17(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2)(rxjs@7.8.2) '@nestjs/core': specifier: ^11.0.4 - version: 11.1.18(@nestjs/common@11.1.17(class-transformer@0.5.1)(class-validator@0.15.1)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/platform-express@11.1.17)(@nestjs/websockets@11.1.17)(reflect-metadata@0.2.2)(rxjs@7.8.2) + version: 11.1.18(@nestjs/common@11.1.17(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/platform-express@11.1.17)(@nestjs/websockets@11.1.17)(reflect-metadata@0.2.2)(rxjs@7.8.2) '@nestjs/platform-express': specifier: ^11.0.4 - version: 11.1.17(@nestjs/common@11.1.17(class-transformer@0.5.1)(class-validator@0.15.1)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.18) + version: 11.1.17(@nestjs/common@11.1.17(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.18) '@nestjs/platform-socket.io': specifier: ^11.0.4 - version: 11.1.17(@nestjs/common@11.1.17(class-transformer@0.5.1)(class-validator@0.15.1)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/websockets@11.1.17)(rxjs@7.8.2) + version: 11.1.17(@nestjs/common@11.1.17(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/websockets@11.1.17)(rxjs@7.8.2) '@nestjs/schedule': specifier: ^6.0.0 - version: 6.1.1(@nestjs/common@11.1.17(class-transformer@0.5.1)(class-validator@0.15.1)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.18) + version: 6.1.1(@nestjs/common@11.1.17(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.18) '@nestjs/swagger': specifier: ^11.0.2 - version: 11.2.6(@nestjs/common@11.1.17(class-transformer@0.5.1)(class-validator@0.15.1)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.18)(class-transformer@0.5.1)(class-validator@0.15.1)(reflect-metadata@0.2.2) + version: 11.2.6(@nestjs/common@11.1.17(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.18)(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2) '@nestjs/websockets': specifier: ^11.0.4 - version: 11.1.17(@nestjs/common@11.1.17(class-transformer@0.5.1)(class-validator@0.15.1)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.18)(@nestjs/platform-socket.io@11.1.17)(reflect-metadata@0.2.2)(rxjs@7.8.2) + version: 11.1.17(@nestjs/common@11.1.17(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.18)(@nestjs/platform-socket.io@11.1.17)(reflect-metadata@0.2.2)(rxjs@7.8.2) '@opentelemetry/api': specifier: ^1.9.0 version: 1.9.0 @@ -501,25 +504,28 @@ importers: version: 2.1.1 nest-commander: specifier: ^3.16.0 - version: 3.20.1(@nestjs/common@11.1.17(class-transformer@0.5.1)(class-validator@0.15.1)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.18)(@types/inquirer@8.2.12)(@types/node@24.12.2)(typescript@6.0.2) + version: 3.20.1(@nestjs/common@11.1.17(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.18)(@types/inquirer@8.2.12)(@types/node@24.12.2)(typescript@6.0.2) nestjs-cls: specifier: ^5.0.0 - version: 5.4.3(@nestjs/common@11.1.17(class-transformer@0.5.1)(class-validator@0.15.1)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.18)(reflect-metadata@0.2.2)(rxjs@7.8.2) + version: 5.4.3(@nestjs/common@11.1.17(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.18)(reflect-metadata@0.2.2)(rxjs@7.8.2) nestjs-kysely: specifier: 3.1.2 - version: 3.1.2(@nestjs/common@11.1.17(class-transformer@0.5.1)(class-validator@0.15.1)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.18)(kysely@0.28.15)(reflect-metadata@0.2.2) + version: 3.1.2(@nestjs/common@11.1.17(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.18)(kysely@0.28.15)(reflect-metadata@0.2.2) nestjs-otel: specifier: ^7.0.0 - version: 7.0.1(@nestjs/common@11.1.17(class-transformer@0.5.1)(class-validator@0.15.1)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.18) + version: 7.0.1(@nestjs/common@11.1.17(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.18) nestjs-zod: specifier: ^5.3.0 - version: 5.3.0(@nestjs/common@11.1.17(class-transformer@0.5.1)(class-validator@0.15.1)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/swagger@11.2.6(@nestjs/common@11.1.17(class-transformer@0.5.1)(class-validator@0.15.1)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.18)(class-transformer@0.5.1)(class-validator@0.15.1)(reflect-metadata@0.2.2))(rxjs@7.8.2)(zod@4.3.6) + version: 5.3.0(@nestjs/common@11.1.17(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/swagger@11.2.6(@nestjs/common@11.1.17(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.18)(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2))(rxjs@7.8.2)(zod@4.3.6) nodemailer: specifier: ^8.0.0 version: 8.0.5 openid-client: specifier: ^6.3.3 version: 6.8.2 + orchestration-api: + specifier: 0.1.54 + version: 0.1.54(@nestjs/platform-express@11.1.17)(class-transformer@0.5.1)(reflect-metadata@0.2.2) pg: specifier: ^8.11.3 version: 8.20.0 @@ -595,7 +601,7 @@ importers: version: 11.0.9(chokidar@4.0.3)(typescript@6.0.2) '@nestjs/testing': specifier: ^11.0.4 - version: 11.1.17(@nestjs/common@11.1.17(class-transformer@0.5.1)(class-validator@0.15.1)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.18)(@nestjs/platform-express@11.1.17) + version: 11.1.17(@nestjs/common@11.1.17(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.18)(@nestjs/platform-express@11.1.17) '@swc/core': specifier: ^1.4.14 version: 1.15.18(@swc/helpers@0.5.17) @@ -809,6 +815,9 @@ importers: maplibre-gl: specifier: ^5.6.2 version: 5.21.0 + orchestration-ui: + specifier: 0.1.54 + version: 0.1.54(@sveltejs/kit@2.57.1(@opentelemetry/api@1.9.0)(@sveltejs/vite-plugin-svelte@7.0.0(svelte@5.55.1)(vite@8.0.5(@emnapi/core@1.9.1)(@emnapi/runtime@1.9.1)(@types/node@25.5.0)(esbuild@0.27.4)(jiti@2.6.1)(sass@1.97.1)(terser@5.44.1)(tsx@4.21.0)(yaml@2.8.3)))(svelte@5.55.1)(typescript@6.0.2)(vite@8.0.5(@emnapi/core@1.9.1)(@emnapi/runtime@1.9.1)(@types/node@25.5.0)(esbuild@0.27.4)(jiti@2.6.1)(sass@1.97.1)(terser@5.44.1)(tsx@4.21.0)(yaml@2.8.3)))(svelte@5.55.1) pmtiles: specifier: ^4.3.0 version: 4.4.0 @@ -2834,6 +2843,10 @@ packages: resolution: {integrity: sha512-Udu3K7SzAo9N013qt7qmm22/wo2hADdheXtBfxFTecp+ogsc0caQNRKEb7pkvvagUGOpG9wJC1ViH6WXs8oXIA==} engines: {node: '>=6'} + '@futo-org/restic-wrapper@1.1.2': + resolution: {integrity: sha512-luTXwUW/5fP7EA2vDkVvPXrTXKSubos7ijv7ofTYNjQqAxOaeIdUvkAz+Le2VtB5jQKOnSCsjjTBgUZtjxiKGg==} + engines: {node: '>=20'} + '@golevelup/nestjs-discovery@5.0.0': resolution: {integrity: sha512-NaIWLCLI+XvneUK05LH2idHLmLNITYT88YnpOuUQmllKtiJNIS3woSt7QXrMZ5k3qUWuZpehEVz1JtlX4I1KyA==} peerDependencies: @@ -3042,11 +3055,21 @@ packages: resolution: {integrity: sha512-UWhy/+Lf8C1dJip5wPfFytI3Vq/9UyDKQE1ROjXwVhT6E/CPgBkRLwHPetjYGPJ4o1JVVpRLnEEJCXdvzqVpGw==} hasBin: true + '@immich/svelte-markdown-preprocess@0.1.0': + resolution: {integrity: sha512-jgSOJEGLPKEXQCNRI4r4YUayeM2b0ZYLdzgKGl891jZBhOQIetlY7rU44kPpV1AA3/8wGDwNFKduIQZZ/qJYzg==} + peerDependencies: + svelte: ^5.0.0 + '@immich/svelte-markdown-preprocess@0.4.1': resolution: {integrity: sha512-/N5dhu3fnRZUoZ+Z9hrIV61o9wi6Uf70TDxqiinXNYlXfqP81p1o77Z5mhbxtNigTNcp6GwpGeHAXRHQrU9JAQ==} peerDependencies: svelte: ^5.0.0 + '@immich/ui@0.59.0': + resolution: {integrity: sha512-7yxvyhhd99T0AHhjMakp7c/U4n0jGAmRO5xpncsRASRvqZve/LAibjr6N5FJc5IAd222DROTMLn6imsxVfqfvg==} + peerDependencies: + svelte: ^5.0.0 + '@immich/ui@0.76.0': resolution: {integrity: sha512-ghxfbC47UPMwQJ65maOUYdduQ/G/zo87Oc2ZUKe6o8KgoHsWxLVjQUw44T3dZdFOhvyS8SsIlkGLuagVcrM9Bg==} peerDependencies: @@ -3502,6 +3525,12 @@ packages: '@nestjs/websockets': optional: true + '@nestjs/event-emitter@3.0.1': + resolution: {integrity: sha512-0Ln/x+7xkU6AJFOcQI9tIhUMXVF7D5itiaQGOyJbXtlAfAIt8gzDdJm+Im7cFzKoWkiW5nCXCPh6GSvdQd/3Dw==} + peerDependencies: + '@nestjs/common': ^10.0.0 || ^11.0.0 + '@nestjs/core': ^10.0.0 || ^11.0.0 + '@nestjs/mapped-types@2.1.0': resolution: {integrity: sha512-W+n+rM69XsFdwORF11UqJahn4J3xi4g/ZEOlJNL6KoW5ygWSmBB2p0S2BZ4FQeS/NDH72e6xIcu35SfJnE8bXw==} peerDependencies: @@ -4765,6 +4794,14 @@ packages: peerDependencies: vite: ^5.2.0 || ^6 || ^7 || ^8 + '@tanstack/query-core@5.95.1': + resolution: {integrity: sha512-RTa+CECs9hNMDR2qH4x6bZEjXXDqnjolwecCgwk7ItW1K9WDjUrnyTrtGv4o6aZc1/6uUMkF6DWlYt78uJpgxw==} + + '@tanstack/svelte-query@6.1.9': + resolution: {integrity: sha512-/0vLdI0qujZ03GRijZp4awDKqAWR6I2TE+OxgLFOyv2y7epoT6Z98B6os0XR/3DhPeCxKdnn/KUVXyfC4xZGVQ==} + peerDependencies: + svelte: ^5.25.0 + '@testing-library/dom@10.4.1': resolution: {integrity: sha512-o4PXJQidqJl82ckFaXUeoAW+XysPLauYI43Abki5hABd853iMhitooc6znOnczgbTYmEP6U6/y1ZyKAIsvMKGg==} engines: {node: '>=18'} @@ -5854,6 +5891,10 @@ packages: resolution: {integrity: sha512-cU8v/EGSrnH+HnxV2z0J7/blxH8gq7Xh2JFT6Aroax7UohdmiJJlxApMxtKfuI7z68NvvVcmR78k2LbT6efhRg==} engines: {node: '>= 18'} + better-sqlite3@12.8.0: + resolution: {integrity: sha512-RxD2Vd96sQDjQr20kdP+F+dK/1OUNiVOl200vKBZY8u0vTwysfolF6Hq+3ZK2+h8My9YvZhHsF+RSGZW2VYrPQ==} + engines: {node: 20.x || 22.x || 23.x || 24.x || 25.x} + big.js@5.2.2: resolution: {integrity: sha512-vyL2OymJxmarO8gxMr0mhChsO9QGwhynfuu4+MHTAW6czfq9humCB7rKpUjDd9YUiDPU4mzpyupFSvOClAwbmQ==} @@ -5861,6 +5902,9 @@ packages: resolution: {integrity: sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==} engines: {node: '>=8'} + bindings@1.5.0: + resolution: {integrity: sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ==} + bits-ui@2.16.3: resolution: {integrity: sha512-5hJ5dEhf5yPzkRFcxzgQHScGodeo0gK0MUUXrdLlRHWaBOBGZiacWLG96j/wwFatKwZvouw7q+sn14i0fx3RIg==} engines: {node: '>=20'} @@ -6129,8 +6173,8 @@ packages: class-transformer@0.5.1: resolution: {integrity: sha512-SQa1Ws6hUbfC98vKGxZH3KFY0Y1lm5Zm0SY8XX9zbK7FJCyVEac3ATW0RIpwzW+oOfmHE5PMPufDG9hCfoEOMw==} - class-validator@0.15.1: - resolution: {integrity: sha512-LqoS80HBBSCVhz/3KloUly0ovokxpdOLR++Al3J3+dHXWt9sTKlKd4eYtoxhxyUjoe5+UcIM+5k9MIxyBWnRTw==} + class-validator@0.14.4: + resolution: {integrity: sha512-AwNusCCam51q703dW82x95tOqQp6oC9HNUl724KxJJOfnKscI8dOloXFgyez7LbTTKWuRBA37FScqVbJEoq8Yw==} clean-css@5.3.3: resolution: {integrity: sha512-D5J+kHaVb/wKSFcyyV75uCn8fiY4sV38XJoe4CUyGQ+mOU/fMVYUdH1hJC+CJQ5uY3EnW27SbJYS4X8BiLrAFg==} @@ -6453,6 +6497,9 @@ packages: resolution: {integrity: sha512-p0SaNjrHOnQeR8/VnfGbmg9te2kfyYSQ7Sc/j/6DtPL3JQvKxmjO9TSjNFpujqV3vEYYBvNNvXSxzyksBWAx1Q==} engines: {node: '>=12.0.0'} + cron-validate@1.5.3: + resolution: {integrity: sha512-jcu8g/3wZL8OBr4MkEcbeIdLpM8pp5Y6UoOlRktcJG3WjgpifijR0s26Yac7ywR0gC2ABtevOsz5mlD3l3gzwA==} + cron@4.4.0: resolution: {integrity: sha512-fkdfq+b+AHI4cKdhZlppHveI/mgz2qpiYxcm+t5E5TsxX7QrLS1VE0+7GENEk9z0EeGPcpSciGv6ez24duWhwQ==} engines: {node: '>=18.x'} @@ -7367,10 +7414,16 @@ packages: event-emitter@0.3.5: resolution: {integrity: sha512-D9rRn9y7kLPnJ+hMq7S/nhvoKwwvVJahBi2BPmx3bvbsEdK3W9ii8cBSGjP+72/LnM4n6fo3+dkCX5FeTQruXA==} + event-iterator@2.0.0: + resolution: {integrity: sha512-KGft0ldl31BZVV//jj+IAIGCxkvvUkkON+ScH6zfoX+l+omX6001ggyRSpI0Io2Hlro0ThXotswCtfzS8UkIiQ==} + event-target-shim@5.0.1: resolution: {integrity: sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ==} engines: {node: '>=6'} + eventemitter2@6.4.9: + resolution: {integrity: sha512-JEPTiaOt9f04oa6NOkc4aH+nVp5I3wEjpHbIPqfgCdD5v5bUzy7xQqwcVO2aDQgOWhI28da57HksMrzK9HlRxg==} + eventemitter3@4.0.7: resolution: {integrity: sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw==} @@ -7402,6 +7455,10 @@ packages: resolution: {integrity: sha512-ox+pcW9m52MGeXMMuZjbdaKgeha9WmWPE7HhVw6GNZ607a9Hx2HyiAUDQm+XdAzv6Y34sahLReCeJRmS9F70Ww==} engines: {node: '>=20.0.0'} + expand-template@2.0.3: + resolution: {integrity: sha512-XYfuKMvj4O35f/pOXLObndIRvyQ+/+6AhODh+OKWj9S9498pHHn/IMszH+gt0fBCRWMNfk1ZSp5x3AifmnI2vg==} + engines: {node: '>=6'} + expect-type@1.3.0: resolution: {integrity: sha512-knvyeauYhqjOYvQ66MznSMs83wmHrCycNEN6Ao+2AeYEfxUIkuiVxdEa1qlGEPK+We3n0THiDciYSsCcgW/DoA==} engines: {node: '>=12.0.0'} @@ -7510,6 +7567,9 @@ packages: resolution: {integrity: sha512-DLkUvGwep3poOV2wpzbHCOnSKGk1LzyXTv+aHFgN2VFl96wnp8YA9YjO2qPzg5PuL8q/SW9Pdi6WTkYOIh995w==} engines: {node: '>=20'} + file-uri-to-path@1.0.0: + resolution: {integrity: sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==} + fill-range@7.1.1: resolution: {integrity: sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==} engines: {node: '>=8'} @@ -7707,6 +7767,9 @@ packages: get-tsconfig@4.13.0: resolution: {integrity: sha512-1VKTZJCwBrvbd+Wn3AOgQP/2Av+TfTCOlE4AcRJE72W1ksZXbAx8PPBR9RzgTeSPzlPMHrbANMH3LbltH73wxQ==} + github-from-package@0.0.0: + resolution: {integrity: sha512-SyHy3T1v2NUXn29OsWdxmK6RwHD+vkj3v8en8AOBZ1wBQ/hCAQ5bAQTD02kW4W9tUp/3Qh6J8r9EvntiyCmOOw==} + github-slugger@1.5.0: resolution: {integrity: sha512-wIh+gKBI9Nshz2o46B0B3f5k/W+WI9ZAv6y5Dn5WJ5SK1t0TnDimB4WE5rmTD05ZAIn8HALCZVmCsvj0w0v0lw==} @@ -8567,6 +8630,10 @@ packages: resolution: {integrity: sha512-r2clcf7HLWvDXaVUEvQymXJY4i3bSOIV3xsL/Upy3ZfSv5HeKsk9tsqbBptLvth5qHEIhxeHTA2jNLyQABkLBA==} engines: {node: '>=20.0.0'} + kysely@0.28.2: + resolution: {integrity: sha512-4YAVLoF0Sf0UTqlhgQMFU9iQECdah7n+13ANkiuVfRvlK+uI0Etbgd7bVP36dKlG+NXWbhGua8vnGt+sdhvT7A==} + engines: {node: '>=18.0.0'} + langium@3.3.1: resolution: {integrity: sha512-QJv/h939gDpvT+9SiLVlY7tZC3xB2qK57v0J04Sh9wpMb6MP1q8gB21L3WIo8T5P1MSMg3Ep14L7KkDCFG3y4w==} engines: {node: '>=16.0.0'} @@ -9334,6 +9401,9 @@ packages: engines: {node: ^18 || >=20} hasBin: true + napi-build-utils@2.0.0: + resolution: {integrity: sha512-GEbrYkbfF7MoNaoh2iGG84Mnf/WZfB0GdGEsM8wz7Expx/LlWf5U8t9nvJKXSp3qr5IsEbK04cBGhol/KwOsWA==} + natural-compare-lite@1.4.0: resolution: {integrity: sha512-Tj+HTDSJJKaZnfiuw+iaF9skdPpTo2GtEly5JHnWV/hfv2Qj/9RKsGISQtLh2ox3l5EAGw487hnBee0sIJ6v2g==} @@ -9407,6 +9477,10 @@ packages: no-case@3.0.4: resolution: {integrity: sha512-fgAN3jGAh+RoxUGZHTSOLJIqUc2wmoBwGR4tbpNAKmmovFoWq0OdRkb0VkldReO2a2iBT/OEulG9XSUc10r3zg==} + node-abi@3.89.0: + resolution: {integrity: sha512-6u9UwL0HlAl21+agMN3YAMXcKByMqwGx+pq+P76vii5f7hTPtKDp08/H9py6DY+cfDw7kQNTGEj/rly3IgbNQA==} + engines: {node: '>=10'} + node-abort-controller@3.1.1: resolution: {integrity: sha512-AGK2yQKIjRuqnc6VkX2Xj5d+QW8xZ87pa1UK6yA6ouUyuxfHuMP6umE5QK7UmTeOAymo+Zx1Fxiuw9rVx8taHQ==} @@ -9601,6 +9675,14 @@ packages: resolution: {integrity: sha512-weP+BZ8MVNnlCm8c0Qdc1WSWq4Qn7I+9CJGm7Qali6g44e/PUzbjNqJX5NJ9ljlNMosfJvg1fKEGILklK9cwnw==} engines: {node: '>=18'} + orchestration-api@0.1.54: + resolution: {integrity: sha512-p5OyYMIlxBZ7bwvxIpBsYsUn1+pmAGfLEudsbwhENl7I1N72TB6yu2hm6EgOD94Q1apO1kEIeibRuCfo2Ea0wA==} + + orchestration-ui@0.1.54: + resolution: {integrity: sha512-QWuX5ijtV5tl6Am0UdQcTPYTzr627/HmlxBgBXYcfd0Bq6bvlM688Nq6mYhJ/1W/41fto/MBOaISl/Z756NS7g==} + peerDependencies: + svelte: ^5.0.0 + p-cancelable@3.0.0: resolution: {integrity: sha512-mlVgR3PGuzlo0MmTdk4cXqXWlwQDLnONTAg6sm62XkMJEiRxN3GL3SffkYvqwonbkJBcrI7Uvv5Zh9yjvn2iUw==} engines: {node: '>=12.20'} @@ -10358,6 +10440,12 @@ packages: resolution: {integrity: sha512-dM0jVuXJPsDN6DvRpea484tCUaMiXWjuCn++HGTqUWzGDjv5tZkEZldAJ/UMlqRYGFrD/etByo4/xOuC/snX2A==} engines: {node: '>=20'} + prebuild-install@7.1.3: + resolution: {integrity: sha512-8Mf2cbV7x1cXPUILADGI3wuhfqWvtiLA1iclTDbFRZkgRQS0NqsPZphna9V+HyTEadheuPmjaJMsbzKQFOzLug==} + engines: {node: '>=10'} + deprecated: No longer maintained. Please contact the author of the relevant native addon; alternatives are available. + hasBin: true + prelude-ls@1.2.1: resolution: {integrity: sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==} engines: {node: '>= 0.8.0'} @@ -10442,6 +10530,9 @@ packages: resolution: {integrity: sha512-WPn+h9RGEExOKdu4bsF4HksG/uzd3cFq3MFtq8PsFeExPse5Ha/VOjQNyHhjboBFwGXGev6muJYTSPAOkROq2g==} engines: {node: '>=18'} + property-expr@2.0.6: + resolution: {integrity: sha512-SVtmxhRE/CGkn3eZY1T6pC8Nln6Fr/lu1mKSgRud0eC73whjGfoAogbn78LkD8aFL0zz3bAFerKSnOl7NlErBA==} + property-information@5.6.0: resolution: {integrity: sha512-YUHSPk+A30YPv+0Qf8i9Mbfe/C0hdPXk1s1jPVToV8pk8BQtpw10ct89Eo7OWkutrwqvT0eicAxlOg3dOAu8JA==} @@ -11038,6 +11129,9 @@ packages: simple-get@3.1.1: resolution: {integrity: sha512-CQ5LTKGfCpvE1K0n2us+kuMPbk/q0EKl82s4aheV9oXjFEz6W/Y7oQFVJuU6QG77hRT4Ghb5RURteF5vnWjupA==} + simple-get@4.0.1: + resolution: {integrity: sha512-brv7p5WgH0jmQJr1ZDDfKDOSeWWg+OVypG99A/5vYGPqJ6pxiaHLy8nxtFjBA7oMa01ebA9gfh1uMCFqOuXxvA==} + simple-icons@15.22.0: resolution: {integrity: sha512-i/w5Ie4tENfGYbdCo2iJ+oies0vOFd8QXWHopKOUzudfLCvnmeheF2PpHp89Z2azpc+c2su3lMiWO/SpP+429A==} engines: {node: '>=0.12.18'} @@ -11451,6 +11545,10 @@ packages: resolution: {integrity: sha512-yEFYrVhod+hdNyx7g5Bnkkb0G6si8HJurOoOEgC8B/O0uXLHlaey/65KRv6cuWBNhBgHKAROVpc7QyYqE5gFng==} engines: {node: '>=20'} + tail@2.2.6: + resolution: {integrity: sha512-IQ6G4wK/t8VBauYiGPLx+d3fA5XjSVagjWV5SIYzvEvglbQjwEcukeYI68JOPpdydjxhZ9sIgzRlSmwSpphHyw==} + engines: {node: '>= 6.0.0'} + tailwind-merge@3.5.0: resolution: {integrity: sha512-I8K9wewnVDkL1NTGoqWmVEIlUcB9gFriAEkXkfCjX5ib8ezGxtR3xD7iZIxrfArjEsH7F1CHD4RFUtxefdqV/A==} @@ -11590,6 +11688,9 @@ packages: resolution: {integrity: sha512-wFH7+SEAcKfJpfLPkrgMPvvwnEtj8W4IurvEyrKsDleXnKLCDw71w8jltvfLa8Rm4qQxxT4jmDBYbJG/z7qoww==} engines: {node: '>=0.12'} + tiny-case@1.0.3: + resolution: {integrity: sha512-Eet/eeMhkO6TX8mnUteS9zgPbUMQa4I6Kkp5ORiBD5476/m+PIRiumP5tmh5ioJpH7k51Kehawy2UDfsnxxY8Q==} + tiny-glob@0.2.9: resolution: {integrity: sha512-g/55ssRPUjShh+xkfx9UPDXqhckHEsHr4Vd9zX55oSdGZc/MD0m3sferOkwWtp98bv+kcVfEHtRJgBVJzelrzg==} @@ -11658,6 +11759,9 @@ packages: resolution: {integrity: sha512-dRXchy+C0IgK8WPC6xvCHFRIWYUbqqdEIKPaKo/AcTUNzwLTK6AH7RjdLWsEZcAN/TBdtfUw3PYEgPr5VPr6ww==} engines: {node: '>=14.16'} + toposort@2.0.2: + resolution: {integrity: sha512-0a5EOkAUp8D4moMi2W8ZF8jcga7BgZd91O/yabJCFY8az+XSzeGyTKs0Aoo897iV1Nj6guFq8orWDS96z91oGg==} + totalist@3.0.1: resolution: {integrity: sha512-sf4i37nQ2LBx4m3wB74y+ubopq6W/dIzXg0FDGjsYnZHVa1Da8FH853wlL2gtUhg+xJXjfk3kUZS3BRoQeoQBQ==} engines: {node: '>=6'} @@ -11737,6 +11841,9 @@ packages: engines: {node: '>=18.0.0'} hasBin: true + tunnel-agent@0.6.0: + resolution: {integrity: sha512-McnNiV1l8RYeY8tBgEpuodCC1mLUdbSN+CYBL7kJsJNInOP8UjDDEwdk6Mw60vdLLrr5NHKZhMAOSrR2NZuQ+w==} + tweetnacl@0.14.5: resolution: {integrity: sha512-KXXFFdAbFXY4geFIwoyNK+f5Z1b7swfXABfL7HXCmoIWMKU3dmS26672A4EeQtDzLKy7SXmfBu51JolvEKwtGA==} @@ -12536,6 +12643,12 @@ packages: resolution: {integrity: sha512-CzhO+pFNo8ajLM2d2IW/R93ipy99LWjtwblvC1RsoSUMZgyLbYFr221TnSNT7GjGdYui6P459mw9JH/g/zW2ug==} engines: {node: '>=18'} + yucca-api-client@0.1.54: + resolution: {integrity: sha512-43xMWTIMBKm1NuvR05TmbKFvbFoEpd7rXvAWBUbgLvUU1ThV/WWdAAoIIvzgiYumEX3xd99B+V5DQ4LXvNpKRQ==} + + yup@1.7.1: + resolution: {integrity: sha512-GKHFX2nXul2/4Dtfxhozv701jLQHdf6J34YDh2cEkpqoo8le5Mg6/LrdseVLrFarmFygZTlfIhHx/QKfb/QWXw==} + zimmerframe@1.1.4: resolution: {integrity: sha512-B58NGBEoc8Y9MWWCQGl/gq9xBCe4IiKM0a2x7GZdQKOW5Exr8S1W24J6OgM1njK8xCRGvAJIL/MxXHf6SkmQKQ==} @@ -15080,10 +15193,14 @@ snapshots: dependencies: '@fortawesome/fontawesome-common-types': 7.1.0 - '@golevelup/nestjs-discovery@5.0.0(@nestjs/common@11.1.17(class-transformer@0.5.1)(class-validator@0.15.1)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.18)': + '@futo-org/restic-wrapper@1.1.2': dependencies: - '@nestjs/common': 11.1.17(class-transformer@0.5.1)(class-validator@0.15.1)(reflect-metadata@0.2.2)(rxjs@7.8.2) - '@nestjs/core': 11.1.18(@nestjs/common@11.1.17(class-transformer@0.5.1)(class-validator@0.15.1)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/platform-express@11.1.17)(@nestjs/websockets@11.1.17)(reflect-metadata@0.2.2)(rxjs@7.8.2) + zod: 4.3.6 + + '@golevelup/nestjs-discovery@5.0.0(@nestjs/common@11.1.17(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.18)': + dependencies: + '@nestjs/common': 11.1.17(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2)(rxjs@7.8.2) + '@nestjs/core': 11.1.18(@nestjs/common@11.1.17(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/platform-express@11.1.17)(@nestjs/websockets@11.1.17)(reflect-metadata@0.2.2)(rxjs@7.8.2) lodash: 4.18.1 '@grpc/grpc-js@1.14.3': @@ -15236,6 +15353,10 @@ snapshots: pg-connection-string: 2.12.0 postgres: 3.4.8 + '@immich/svelte-markdown-preprocess@0.1.0(svelte@5.55.1)': + dependencies: + svelte: 5.55.1 + '@immich/svelte-markdown-preprocess@0.4.1(svelte@5.55.1)': dependencies: front-matter: 4.0.2 @@ -15243,6 +15364,38 @@ snapshots: node-emoji: 2.2.0 svelte: 5.55.1 + '@immich/ui@0.59.0(@sveltejs/kit@2.57.1(@opentelemetry/api@1.9.0)(@sveltejs/vite-plugin-svelte@7.0.0(svelte@5.55.1)(vite@8.0.5(@emnapi/core@1.9.1)(@emnapi/runtime@1.9.1)(@types/node@25.5.0)(esbuild@0.27.4)(jiti@2.6.1)(sass@1.97.1)(terser@5.44.1)(tsx@4.21.0)(yaml@2.8.3)))(svelte@5.55.1)(typescript@6.0.2)(vite@8.0.5(@emnapi/core@1.9.1)(@emnapi/runtime@1.9.1)(@types/node@25.5.0)(esbuild@0.27.4)(jiti@2.6.1)(sass@1.97.1)(terser@5.44.1)(tsx@4.21.0)(yaml@2.8.3)))(svelte@5.55.1)': + dependencies: + '@immich/svelte-markdown-preprocess': 0.1.0(svelte@5.55.1) + '@internationalized/date': 3.12.0 + '@mdi/js': 7.4.47 + bits-ui: 2.16.3(@internationalized/date@3.12.0)(@sveltejs/kit@2.57.1(@opentelemetry/api@1.9.0)(@sveltejs/vite-plugin-svelte@7.0.0(svelte@5.55.1)(vite@8.0.5(@emnapi/core@1.9.1)(@emnapi/runtime@1.9.1)(@types/node@25.5.0)(esbuild@0.27.4)(jiti@2.6.1)(sass@1.97.1)(terser@5.44.1)(tsx@4.21.0)(yaml@2.8.3)))(svelte@5.55.1)(typescript@6.0.2)(vite@8.0.5(@emnapi/core@1.9.1)(@emnapi/runtime@1.9.1)(@types/node@25.5.0)(esbuild@0.27.4)(jiti@2.6.1)(sass@1.97.1)(terser@5.44.1)(tsx@4.21.0)(yaml@2.8.3)))(svelte@5.55.1) + luxon: 3.7.2 + simple-icons: 16.13.0 + svelte: 5.55.1 + svelte-highlight: 7.9.0 + tailwind-merge: 3.5.0 + tailwind-variants: 3.2.2(tailwind-merge@3.5.0)(tailwindcss@4.2.2) + tailwindcss: 4.2.2 + transitivePeerDependencies: + - '@sveltejs/kit' + + '@immich/ui@0.59.0(svelte@5.55.1)': + dependencies: + '@immich/svelte-markdown-preprocess': 0.1.0(svelte@5.55.1) + '@internationalized/date': 3.12.0 + '@mdi/js': 7.4.47 + bits-ui: 2.16.3(@internationalized/date@3.12.0)(svelte@5.55.1) + luxon: 3.7.2 + simple-icons: 16.13.0 + svelte: 5.55.1 + svelte-highlight: 7.9.0 + tailwind-merge: 3.5.0 + tailwind-variants: 3.2.2(tailwind-merge@3.5.0)(tailwindcss@4.2.2) + tailwindcss: 4.2.2 + transitivePeerDependencies: + - '@sveltejs/kit' + '@immich/ui@0.76.0(@sveltejs/kit@2.57.1(@opentelemetry/api@1.9.0)(@sveltejs/vite-plugin-svelte@7.0.0(svelte@5.55.1)(vite@8.0.5(@emnapi/core@1.9.1)(@emnapi/runtime@1.9.1)(@types/node@25.5.0)(esbuild@0.27.4)(jiti@2.6.1)(sass@1.97.1)(terser@5.44.1)(tsx@4.21.0)(yaml@2.8.3)))(svelte@5.55.1)(typescript@6.0.2)(vite@8.0.5(@emnapi/core@1.9.1)(@emnapi/runtime@1.9.1)(@types/node@25.5.0)(esbuild@0.27.4)(jiti@2.6.1)(sass@1.97.1)(terser@5.44.1)(tsx@4.21.0)(yaml@2.8.3)))(svelte@5.55.1)': dependencies: '@immich/svelte-markdown-preprocess': 0.4.1(svelte@5.55.1) @@ -15718,17 +15871,17 @@ snapshots: '@tybys/wasm-util': 0.10.1 optional: true - '@nestjs/bull-shared@11.0.4(@nestjs/common@11.1.17(class-transformer@0.5.1)(class-validator@0.15.1)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.18)': + '@nestjs/bull-shared@11.0.4(@nestjs/common@11.1.17(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.18)': dependencies: - '@nestjs/common': 11.1.17(class-transformer@0.5.1)(class-validator@0.15.1)(reflect-metadata@0.2.2)(rxjs@7.8.2) - '@nestjs/core': 11.1.18(@nestjs/common@11.1.17(class-transformer@0.5.1)(class-validator@0.15.1)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/platform-express@11.1.17)(@nestjs/websockets@11.1.17)(reflect-metadata@0.2.2)(rxjs@7.8.2) + '@nestjs/common': 11.1.17(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2)(rxjs@7.8.2) + '@nestjs/core': 11.1.18(@nestjs/common@11.1.17(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/platform-express@11.1.17)(@nestjs/websockets@11.1.17)(reflect-metadata@0.2.2)(rxjs@7.8.2) tslib: 2.8.1 - '@nestjs/bullmq@11.0.4(@nestjs/common@11.1.17(class-transformer@0.5.1)(class-validator@0.15.1)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.18)(bullmq@5.71.0)': + '@nestjs/bullmq@11.0.4(@nestjs/common@11.1.17(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.18)(bullmq@5.71.0)': dependencies: - '@nestjs/bull-shared': 11.0.4(@nestjs/common@11.1.17(class-transformer@0.5.1)(class-validator@0.15.1)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.18) - '@nestjs/common': 11.1.17(class-transformer@0.5.1)(class-validator@0.15.1)(reflect-metadata@0.2.2)(rxjs@7.8.2) - '@nestjs/core': 11.1.18(@nestjs/common@11.1.17(class-transformer@0.5.1)(class-validator@0.15.1)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/platform-express@11.1.17)(@nestjs/websockets@11.1.17)(reflect-metadata@0.2.2)(rxjs@7.8.2) + '@nestjs/bull-shared': 11.0.4(@nestjs/common@11.1.17(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.18) + '@nestjs/common': 11.1.17(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2)(rxjs@7.8.2) + '@nestjs/core': 11.1.18(@nestjs/common@11.1.17(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/platform-express@11.1.17)(@nestjs/websockets@11.1.17)(reflect-metadata@0.2.2)(rxjs@7.8.2) bullmq: 5.71.0 tslib: 2.8.1 @@ -15760,7 +15913,7 @@ snapshots: - uglify-js - webpack-cli - '@nestjs/common@11.1.17(class-transformer@0.5.1)(class-validator@0.15.1)(reflect-metadata@0.2.2)(rxjs@7.8.2)': + '@nestjs/common@11.1.17(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2)(rxjs@7.8.2)': dependencies: file-type: 21.3.2 iterare: 1.2.1 @@ -15771,13 +15924,13 @@ snapshots: uid: 2.0.2 optionalDependencies: class-transformer: 0.5.1 - class-validator: 0.15.1 + class-validator: 0.14.4 transitivePeerDependencies: - supports-color - '@nestjs/core@11.1.18(@nestjs/common@11.1.17(class-transformer@0.5.1)(class-validator@0.15.1)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/platform-express@11.1.17)(@nestjs/websockets@11.1.17)(reflect-metadata@0.2.2)(rxjs@7.8.2)': + '@nestjs/core@11.1.18(@nestjs/common@11.1.17(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/platform-express@11.1.17)(@nestjs/websockets@11.1.17)(reflect-metadata@0.2.2)(rxjs@7.8.2)': dependencies: - '@nestjs/common': 11.1.17(class-transformer@0.5.1)(class-validator@0.15.1)(reflect-metadata@0.2.2)(rxjs@7.8.2) + '@nestjs/common': 11.1.17(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2)(rxjs@7.8.2) '@nuxt/opencollective': 0.4.1 fast-safe-stringify: 2.1.1 iterare: 1.2.1 @@ -15787,21 +15940,27 @@ snapshots: tslib: 2.8.1 uid: 2.0.2 optionalDependencies: - '@nestjs/platform-express': 11.1.17(@nestjs/common@11.1.17(class-transformer@0.5.1)(class-validator@0.15.1)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.18) - '@nestjs/websockets': 11.1.17(@nestjs/common@11.1.17(class-transformer@0.5.1)(class-validator@0.15.1)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.18)(@nestjs/platform-socket.io@11.1.17)(reflect-metadata@0.2.2)(rxjs@7.8.2) + '@nestjs/platform-express': 11.1.17(@nestjs/common@11.1.17(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.18) + '@nestjs/websockets': 11.1.17(@nestjs/common@11.1.17(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.18)(@nestjs/platform-socket.io@11.1.17)(reflect-metadata@0.2.2)(rxjs@7.8.2) - '@nestjs/mapped-types@2.1.0(@nestjs/common@11.1.17(class-transformer@0.5.1)(class-validator@0.15.1)(reflect-metadata@0.2.2)(rxjs@7.8.2))(class-transformer@0.5.1)(class-validator@0.15.1)(reflect-metadata@0.2.2)': + '@nestjs/event-emitter@3.0.1(@nestjs/common@11.1.17(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.18)': dependencies: - '@nestjs/common': 11.1.17(class-transformer@0.5.1)(class-validator@0.15.1)(reflect-metadata@0.2.2)(rxjs@7.8.2) + '@nestjs/common': 11.1.17(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2)(rxjs@7.8.2) + '@nestjs/core': 11.1.18(@nestjs/common@11.1.17(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/platform-express@11.1.17)(@nestjs/websockets@11.1.17)(reflect-metadata@0.2.2)(rxjs@7.8.2) + eventemitter2: 6.4.9 + + '@nestjs/mapped-types@2.1.0(@nestjs/common@11.1.17(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2)(rxjs@7.8.2))(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2)': + dependencies: + '@nestjs/common': 11.1.17(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2)(rxjs@7.8.2) reflect-metadata: 0.2.2 optionalDependencies: class-transformer: 0.5.1 - class-validator: 0.15.1 + class-validator: 0.14.4 - '@nestjs/platform-express@11.1.17(@nestjs/common@11.1.17(class-transformer@0.5.1)(class-validator@0.15.1)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.18)': + '@nestjs/platform-express@11.1.17(@nestjs/common@11.1.17(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.18)': dependencies: - '@nestjs/common': 11.1.17(class-transformer@0.5.1)(class-validator@0.15.1)(reflect-metadata@0.2.2)(rxjs@7.8.2) - '@nestjs/core': 11.1.18(@nestjs/common@11.1.17(class-transformer@0.5.1)(class-validator@0.15.1)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/platform-express@11.1.17)(@nestjs/websockets@11.1.17)(reflect-metadata@0.2.2)(rxjs@7.8.2) + '@nestjs/common': 11.1.17(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2)(rxjs@7.8.2) + '@nestjs/core': 11.1.18(@nestjs/common@11.1.17(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/platform-express@11.1.17)(@nestjs/websockets@11.1.17)(reflect-metadata@0.2.2)(rxjs@7.8.2) cors: 2.8.6 express: 5.2.1 multer: 2.1.1 @@ -15810,10 +15969,10 @@ snapshots: transitivePeerDependencies: - supports-color - '@nestjs/platform-socket.io@11.1.17(@nestjs/common@11.1.17(class-transformer@0.5.1)(class-validator@0.15.1)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/websockets@11.1.17)(rxjs@7.8.2)': + '@nestjs/platform-socket.io@11.1.17(@nestjs/common@11.1.17(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/websockets@11.1.17)(rxjs@7.8.2)': dependencies: - '@nestjs/common': 11.1.17(class-transformer@0.5.1)(class-validator@0.15.1)(reflect-metadata@0.2.2)(rxjs@7.8.2) - '@nestjs/websockets': 11.1.17(@nestjs/common@11.1.17(class-transformer@0.5.1)(class-validator@0.15.1)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.18)(@nestjs/platform-socket.io@11.1.17)(reflect-metadata@0.2.2)(rxjs@7.8.2) + '@nestjs/common': 11.1.17(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2)(rxjs@7.8.2) + '@nestjs/websockets': 11.1.17(@nestjs/common@11.1.17(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.18)(@nestjs/platform-socket.io@11.1.17)(reflect-metadata@0.2.2)(rxjs@7.8.2) rxjs: 7.8.2 socket.io: 4.8.3 tslib: 2.8.1 @@ -15822,10 +15981,10 @@ snapshots: - supports-color - utf-8-validate - '@nestjs/schedule@6.1.1(@nestjs/common@11.1.17(class-transformer@0.5.1)(class-validator@0.15.1)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.18)': + '@nestjs/schedule@6.1.1(@nestjs/common@11.1.17(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.18)': dependencies: - '@nestjs/common': 11.1.17(class-transformer@0.5.1)(class-validator@0.15.1)(reflect-metadata@0.2.2)(rxjs@7.8.2) - '@nestjs/core': 11.1.18(@nestjs/common@11.1.17(class-transformer@0.5.1)(class-validator@0.15.1)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/platform-express@11.1.17)(@nestjs/websockets@11.1.17)(reflect-metadata@0.2.2)(rxjs@7.8.2) + '@nestjs/common': 11.1.17(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2)(rxjs@7.8.2) + '@nestjs/core': 11.1.18(@nestjs/common@11.1.17(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/platform-express@11.1.17)(@nestjs/websockets@11.1.17)(reflect-metadata@0.2.2)(rxjs@7.8.2) cron: 4.4.0 '@nestjs/schematics@11.0.9(chokidar@4.0.3)(typescript@5.9.3)': @@ -15850,12 +16009,12 @@ snapshots: transitivePeerDependencies: - chokidar - '@nestjs/swagger@11.2.6(@nestjs/common@11.1.17(class-transformer@0.5.1)(class-validator@0.15.1)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.18)(class-transformer@0.5.1)(class-validator@0.15.1)(reflect-metadata@0.2.2)': + '@nestjs/swagger@11.2.6(@nestjs/common@11.1.17(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.18)(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2)': dependencies: '@microsoft/tsdoc': 0.16.0 - '@nestjs/common': 11.1.17(class-transformer@0.5.1)(class-validator@0.15.1)(reflect-metadata@0.2.2)(rxjs@7.8.2) - '@nestjs/core': 11.1.18(@nestjs/common@11.1.17(class-transformer@0.5.1)(class-validator@0.15.1)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/platform-express@11.1.17)(@nestjs/websockets@11.1.17)(reflect-metadata@0.2.2)(rxjs@7.8.2) - '@nestjs/mapped-types': 2.1.0(@nestjs/common@11.1.17(class-transformer@0.5.1)(class-validator@0.15.1)(reflect-metadata@0.2.2)(rxjs@7.8.2))(class-transformer@0.5.1)(class-validator@0.15.1)(reflect-metadata@0.2.2) + '@nestjs/common': 11.1.17(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2)(rxjs@7.8.2) + '@nestjs/core': 11.1.18(@nestjs/common@11.1.17(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/platform-express@11.1.17)(@nestjs/websockets@11.1.17)(reflect-metadata@0.2.2)(rxjs@7.8.2) + '@nestjs/mapped-types': 2.1.0(@nestjs/common@11.1.17(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2)(rxjs@7.8.2))(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2) js-yaml: 4.1.1 lodash: 4.17.23 path-to-regexp: 8.3.0 @@ -15863,27 +16022,27 @@ snapshots: swagger-ui-dist: 5.31.0 optionalDependencies: class-transformer: 0.5.1 - class-validator: 0.15.1 + class-validator: 0.14.4 - '@nestjs/testing@11.1.17(@nestjs/common@11.1.17(class-transformer@0.5.1)(class-validator@0.15.1)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.18)(@nestjs/platform-express@11.1.17)': + '@nestjs/testing@11.1.17(@nestjs/common@11.1.17(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.18)(@nestjs/platform-express@11.1.17)': dependencies: - '@nestjs/common': 11.1.17(class-transformer@0.5.1)(class-validator@0.15.1)(reflect-metadata@0.2.2)(rxjs@7.8.2) - '@nestjs/core': 11.1.18(@nestjs/common@11.1.17(class-transformer@0.5.1)(class-validator@0.15.1)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/platform-express@11.1.17)(@nestjs/websockets@11.1.17)(reflect-metadata@0.2.2)(rxjs@7.8.2) + '@nestjs/common': 11.1.17(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2)(rxjs@7.8.2) + '@nestjs/core': 11.1.18(@nestjs/common@11.1.17(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/platform-express@11.1.17)(@nestjs/websockets@11.1.17)(reflect-metadata@0.2.2)(rxjs@7.8.2) tslib: 2.8.1 optionalDependencies: - '@nestjs/platform-express': 11.1.17(@nestjs/common@11.1.17(class-transformer@0.5.1)(class-validator@0.15.1)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.18) + '@nestjs/platform-express': 11.1.17(@nestjs/common@11.1.17(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.18) - '@nestjs/websockets@11.1.17(@nestjs/common@11.1.17(class-transformer@0.5.1)(class-validator@0.15.1)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.18)(@nestjs/platform-socket.io@11.1.17)(reflect-metadata@0.2.2)(rxjs@7.8.2)': + '@nestjs/websockets@11.1.17(@nestjs/common@11.1.17(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.18)(@nestjs/platform-socket.io@11.1.17)(reflect-metadata@0.2.2)(rxjs@7.8.2)': dependencies: - '@nestjs/common': 11.1.17(class-transformer@0.5.1)(class-validator@0.15.1)(reflect-metadata@0.2.2)(rxjs@7.8.2) - '@nestjs/core': 11.1.18(@nestjs/common@11.1.17(class-transformer@0.5.1)(class-validator@0.15.1)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/platform-express@11.1.17)(@nestjs/websockets@11.1.17)(reflect-metadata@0.2.2)(rxjs@7.8.2) + '@nestjs/common': 11.1.17(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2)(rxjs@7.8.2) + '@nestjs/core': 11.1.18(@nestjs/common@11.1.17(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/platform-express@11.1.17)(@nestjs/websockets@11.1.17)(reflect-metadata@0.2.2)(rxjs@7.8.2) iterare: 1.2.1 object-hash: 3.0.0 reflect-metadata: 0.2.2 rxjs: 7.8.2 tslib: 2.8.1 optionalDependencies: - '@nestjs/platform-socket.io': 11.1.17(@nestjs/common@11.1.17(class-transformer@0.5.1)(class-validator@0.15.1)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/websockets@11.1.17)(rxjs@7.8.2) + '@nestjs/platform-socket.io': 11.1.17(@nestjs/common@11.1.17(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/websockets@11.1.17)(rxjs@7.8.2) '@noble/hashes@1.8.0': {} @@ -16942,6 +17101,13 @@ snapshots: tailwindcss: 4.2.2 vite: 8.0.5(@emnapi/core@1.9.1)(@emnapi/runtime@1.9.1)(@types/node@25.5.0)(esbuild@0.27.4)(jiti@2.6.1)(sass@1.97.1)(terser@5.44.1)(tsx@4.21.0)(yaml@2.8.3) + '@tanstack/query-core@5.95.1': {} + + '@tanstack/svelte-query@6.1.9(svelte@5.55.1)': + dependencies: + '@tanstack/query-core': 5.95.1 + svelte: 5.55.1 + '@testing-library/dom@10.4.1': dependencies: '@babel/code-frame': 7.29.0 @@ -18263,10 +18429,19 @@ snapshots: transitivePeerDependencies: - supports-color + better-sqlite3@12.8.0: + dependencies: + bindings: 1.5.0 + prebuild-install: 7.1.3 + big.js@5.2.2: {} binary-extensions@2.3.0: {} + bindings@1.5.0: + dependencies: + file-uri-to-path: 1.0.0 + bits-ui@2.16.3(@internationalized/date@3.12.0)(@sveltejs/kit@2.57.1(@opentelemetry/api@1.9.0)(@sveltejs/vite-plugin-svelte@7.0.0(svelte@5.55.1)(vite@8.0.5(@emnapi/core@1.9.1)(@emnapi/runtime@1.9.1)(@types/node@25.5.0)(esbuild@0.27.4)(jiti@2.6.1)(sass@1.97.1)(terser@5.44.1)(tsx@4.21.0)(yaml@2.8.3)))(svelte@5.55.1)(typescript@6.0.2)(vite@8.0.5(@emnapi/core@1.9.1)(@emnapi/runtime@1.9.1)(@types/node@25.5.0)(esbuild@0.27.4)(jiti@2.6.1)(sass@1.97.1)(terser@5.44.1)(tsx@4.21.0)(yaml@2.8.3)))(svelte@5.55.1): dependencies: '@floating-ui/core': 1.7.3 @@ -18280,6 +18455,19 @@ snapshots: transitivePeerDependencies: - '@sveltejs/kit' + bits-ui@2.16.3(@internationalized/date@3.12.0)(svelte@5.55.1): + dependencies: + '@floating-ui/core': 1.7.3 + '@floating-ui/dom': 1.7.4 + '@internationalized/date': 3.12.0 + esm-env: 1.2.2 + runed: 0.35.1(svelte@5.55.1) + svelte: 5.55.1 + svelte-toolbelt: 0.10.6(svelte@5.55.1) + tabbable: 6.4.0 + transitivePeerDependencies: + - '@sveltejs/kit' + bl@4.1.0: dependencies: buffer: 5.7.1 @@ -18614,12 +18802,11 @@ snapshots: class-transformer@0.5.1: optional: true - class-validator@0.15.1: + class-validator@0.14.4: dependencies: '@types/validator': 13.15.10 libphonenumber-js: 1.12.38 validator: 13.15.26 - optional: true clean-css@5.3.3: dependencies: @@ -18929,6 +19116,10 @@ snapshots: dependencies: luxon: 3.7.2 + cron-validate@1.5.3: + dependencies: + yup: 1.7.1 + cron@4.4.0: dependencies: '@types/luxon': 3.7.1 @@ -20010,8 +20201,12 @@ snapshots: d: 1.0.2 es5-ext: 0.10.64 + event-iterator@2.0.0: {} + event-target-shim@5.0.1: {} + eventemitter2@6.4.9: {} + eventemitter3@4.0.7: {} events-universal@1.0.1: @@ -20052,6 +20247,8 @@ snapshots: optionalDependencies: exiftool-vendored.exe: 13.53.0 + expand-template@2.0.3: {} + expect-type@1.3.0: {} exponential-backoff@3.1.3: {} @@ -20223,6 +20420,8 @@ snapshots: transitivePeerDependencies: - supports-color + file-uri-to-path@1.0.0: {} + fill-range@7.1.1: dependencies: to-regex-range: 5.0.1 @@ -20439,6 +20638,8 @@ snapshots: dependencies: resolve-pkg-maps: 1.0.0 + github-from-package@0.0.0: {} + github-slugger@1.5.0: {} gl-matrix@3.4.4: {} @@ -21462,6 +21663,8 @@ snapshots: kysely@0.28.15: {} + kysely@0.28.2: {} + langium@3.3.1: dependencies: chevrotain: 11.0.3 @@ -21496,8 +21699,7 @@ snapshots: prelude-ls: 1.2.1 type-check: 0.4.0 - libphonenumber-js@1.12.38: - optional: true + libphonenumber-js@1.12.38: {} lightningcss-android-arm64@1.32.0: optional: true @@ -22490,6 +22692,8 @@ snapshots: nanoid@5.1.7: {} + napi-build-utils@2.0.0: {} + natural-compare-lite@1.4.0: {} natural-compare@1.4.0: {} @@ -22509,12 +22713,12 @@ snapshots: neo-async@2.6.2: {} - nest-commander@3.20.1(@nestjs/common@11.1.17(class-transformer@0.5.1)(class-validator@0.15.1)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.18)(@types/inquirer@8.2.12)(@types/node@24.12.2)(typescript@6.0.2): + nest-commander@3.20.1(@nestjs/common@11.1.17(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.18)(@types/inquirer@8.2.12)(@types/node@24.12.2)(typescript@6.0.2): dependencies: '@fig/complete-commander': 3.2.0(commander@11.1.0) - '@golevelup/nestjs-discovery': 5.0.0(@nestjs/common@11.1.17(class-transformer@0.5.1)(class-validator@0.15.1)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.18) - '@nestjs/common': 11.1.17(class-transformer@0.5.1)(class-validator@0.15.1)(reflect-metadata@0.2.2)(rxjs@7.8.2) - '@nestjs/core': 11.1.18(@nestjs/common@11.1.17(class-transformer@0.5.1)(class-validator@0.15.1)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/platform-express@11.1.17)(@nestjs/websockets@11.1.17)(reflect-metadata@0.2.2)(rxjs@7.8.2) + '@golevelup/nestjs-discovery': 5.0.0(@nestjs/common@11.1.17(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.18) + '@nestjs/common': 11.1.17(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2)(rxjs@7.8.2) + '@nestjs/core': 11.1.18(@nestjs/common@11.1.17(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/platform-express@11.1.17)(@nestjs/websockets@11.1.17)(reflect-metadata@0.2.2)(rxjs@7.8.2) '@types/inquirer': 8.2.12 commander: 11.1.0 cosmiconfig: 8.3.6(typescript@6.0.2) @@ -22523,38 +22727,46 @@ snapshots: - '@types/node' - typescript - nestjs-cls@5.4.3(@nestjs/common@11.1.17(class-transformer@0.5.1)(class-validator@0.15.1)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.18)(reflect-metadata@0.2.2)(rxjs@7.8.2): + nestjs-cls@5.4.3(@nestjs/common@11.1.17(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.18)(reflect-metadata@0.2.2)(rxjs@7.8.2): dependencies: - '@nestjs/common': 11.1.17(class-transformer@0.5.1)(class-validator@0.15.1)(reflect-metadata@0.2.2)(rxjs@7.8.2) - '@nestjs/core': 11.1.18(@nestjs/common@11.1.17(class-transformer@0.5.1)(class-validator@0.15.1)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/platform-express@11.1.17)(@nestjs/websockets@11.1.17)(reflect-metadata@0.2.2)(rxjs@7.8.2) + '@nestjs/common': 11.1.17(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2)(rxjs@7.8.2) + '@nestjs/core': 11.1.18(@nestjs/common@11.1.17(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/platform-express@11.1.17)(@nestjs/websockets@11.1.17)(reflect-metadata@0.2.2)(rxjs@7.8.2) reflect-metadata: 0.2.2 rxjs: 7.8.2 - nestjs-kysely@3.1.2(@nestjs/common@11.1.17(class-transformer@0.5.1)(class-validator@0.15.1)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.18)(kysely@0.28.15)(reflect-metadata@0.2.2): + nestjs-kysely@3.1.2(@nestjs/common@11.1.17(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.18)(kysely@0.28.15)(reflect-metadata@0.2.2): dependencies: - '@nestjs/common': 11.1.17(class-transformer@0.5.1)(class-validator@0.15.1)(reflect-metadata@0.2.2)(rxjs@7.8.2) - '@nestjs/core': 11.1.18(@nestjs/common@11.1.17(class-transformer@0.5.1)(class-validator@0.15.1)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/platform-express@11.1.17)(@nestjs/websockets@11.1.17)(reflect-metadata@0.2.2)(rxjs@7.8.2) + '@nestjs/common': 11.1.17(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2)(rxjs@7.8.2) + '@nestjs/core': 11.1.18(@nestjs/common@11.1.17(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/platform-express@11.1.17)(@nestjs/websockets@11.1.17)(reflect-metadata@0.2.2)(rxjs@7.8.2) kysely: 0.28.15 reflect-metadata: 0.2.2 tslib: 2.8.1 - nestjs-otel@7.0.1(@nestjs/common@11.1.17(class-transformer@0.5.1)(class-validator@0.15.1)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.18): + nestjs-kysely@3.1.2(@nestjs/common@11.1.17(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.18)(kysely@0.28.2)(reflect-metadata@0.2.2): dependencies: - '@nestjs/common': 11.1.17(class-transformer@0.5.1)(class-validator@0.15.1)(reflect-metadata@0.2.2)(rxjs@7.8.2) - '@nestjs/core': 11.1.18(@nestjs/common@11.1.17(class-transformer@0.5.1)(class-validator@0.15.1)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/platform-express@11.1.17)(@nestjs/websockets@11.1.17)(reflect-metadata@0.2.2)(rxjs@7.8.2) + '@nestjs/common': 11.1.17(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2)(rxjs@7.8.2) + '@nestjs/core': 11.1.18(@nestjs/common@11.1.17(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/platform-express@11.1.17)(@nestjs/websockets@11.1.17)(reflect-metadata@0.2.2)(rxjs@7.8.2) + kysely: 0.28.2 + reflect-metadata: 0.2.2 + tslib: 2.8.1 + + nestjs-otel@7.0.1(@nestjs/common@11.1.17(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.18): + dependencies: + '@nestjs/common': 11.1.17(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2)(rxjs@7.8.2) + '@nestjs/core': 11.1.18(@nestjs/common@11.1.17(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/platform-express@11.1.17)(@nestjs/websockets@11.1.17)(reflect-metadata@0.2.2)(rxjs@7.8.2) '@opentelemetry/api': 1.9.0 '@opentelemetry/host-metrics': 0.36.2(@opentelemetry/api@1.9.0) response-time: 2.3.4 tslib: 2.8.1 - nestjs-zod@5.3.0(@nestjs/common@11.1.17(class-transformer@0.5.1)(class-validator@0.15.1)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/swagger@11.2.6(@nestjs/common@11.1.17(class-transformer@0.5.1)(class-validator@0.15.1)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.18)(class-transformer@0.5.1)(class-validator@0.15.1)(reflect-metadata@0.2.2))(rxjs@7.8.2)(zod@4.3.6): + nestjs-zod@5.3.0(@nestjs/common@11.1.17(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/swagger@11.2.6(@nestjs/common@11.1.17(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.18)(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2))(rxjs@7.8.2)(zod@4.3.6): dependencies: - '@nestjs/common': 11.1.17(class-transformer@0.5.1)(class-validator@0.15.1)(reflect-metadata@0.2.2)(rxjs@7.8.2) + '@nestjs/common': 11.1.17(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2)(rxjs@7.8.2) deepmerge: 4.3.1 rxjs: 7.8.2 zod: 4.3.6 optionalDependencies: - '@nestjs/swagger': 11.2.6(@nestjs/common@11.1.17(class-transformer@0.5.1)(class-validator@0.15.1)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.18)(class-transformer@0.5.1)(class-validator@0.15.1)(reflect-metadata@0.2.2) + '@nestjs/swagger': 11.2.6(@nestjs/common@11.1.17(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.18)(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2) next-tick@1.1.0: {} @@ -22563,6 +22775,10 @@ snapshots: lower-case: 2.0.2 tslib: 2.8.1 + node-abi@3.89.0: + dependencies: + semver: 7.7.4 + node-abort-controller@3.1.1: {} node-addon-api@4.3.0: {} @@ -22797,6 +23013,75 @@ snapshots: string-width: 7.2.0 strip-ansi: 7.2.0 + orchestration-api@0.1.54(@nestjs/platform-express@11.1.17)(class-transformer@0.5.1)(reflect-metadata@0.2.2): + dependencies: + '@futo-org/restic-wrapper': 1.1.2 + '@nestjs/common': 11.1.17(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2)(rxjs@7.8.2) + '@nestjs/core': 11.1.18(@nestjs/common@11.1.17(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/platform-express@11.1.17)(@nestjs/websockets@11.1.17)(reflect-metadata@0.2.2)(rxjs@7.8.2) + '@nestjs/event-emitter': 3.0.1(@nestjs/common@11.1.17(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.18) + '@nestjs/platform-socket.io': 11.1.17(@nestjs/common@11.1.17(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/websockets@11.1.17)(rxjs@7.8.2) + '@nestjs/schedule': 6.1.1(@nestjs/common@11.1.17(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.18) + '@nestjs/websockets': 11.1.17(@nestjs/common@11.1.17(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.18)(@nestjs/platform-socket.io@11.1.17)(reflect-metadata@0.2.2)(rxjs@7.8.2) + better-sqlite3: 12.8.0 + class-validator: 0.14.4 + cookie: 1.1.1 + cron: 4.4.0 + event-iterator: 2.0.0 + express: 5.2.1 + kysely: 0.28.2 + nestjs-kysely: 3.1.2(@nestjs/common@11.1.17(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.18)(kysely@0.28.2)(reflect-metadata@0.2.2) + openid-client: 6.8.2 + rxjs: 7.8.2 + socket.io: 4.8.3 + tail: 2.2.6 + yucca-api-client: 0.1.54 + transitivePeerDependencies: + - '@nestjs/microservices' + - '@nestjs/platform-express' + - bufferutil + - class-transformer + - reflect-metadata + - supports-color + - utf-8-validate + + orchestration-ui@0.1.54(@sveltejs/kit@2.57.1(@opentelemetry/api@1.9.0)(@sveltejs/vite-plugin-svelte@7.0.0(svelte@5.55.1)(vite@8.0.5(@emnapi/core@1.9.1)(@emnapi/runtime@1.9.1)(@types/node@25.5.0)(esbuild@0.27.4)(jiti@2.6.1)(sass@1.97.1)(terser@5.44.1)(tsx@4.21.0)(yaml@2.8.3)))(svelte@5.55.1)(typescript@6.0.2)(vite@8.0.5(@emnapi/core@1.9.1)(@emnapi/runtime@1.9.1)(@types/node@25.5.0)(esbuild@0.27.4)(jiti@2.6.1)(sass@1.97.1)(terser@5.44.1)(tsx@4.21.0)(yaml@2.8.3)))(svelte@5.55.1): + dependencies: + '@immich/ui': 0.59.0(@sveltejs/kit@2.57.1(@opentelemetry/api@1.9.0)(@sveltejs/vite-plugin-svelte@7.0.0(svelte@5.55.1)(vite@8.0.5(@emnapi/core@1.9.1)(@emnapi/runtime@1.9.1)(@types/node@25.5.0)(esbuild@0.27.4)(jiti@2.6.1)(sass@1.97.1)(terser@5.44.1)(tsx@4.21.0)(yaml@2.8.3)))(svelte@5.55.1)(typescript@6.0.2)(vite@8.0.5(@emnapi/core@1.9.1)(@emnapi/runtime@1.9.1)(@types/node@25.5.0)(esbuild@0.27.4)(jiti@2.6.1)(sass@1.97.1)(terser@5.44.1)(tsx@4.21.0)(yaml@2.8.3)))(svelte@5.55.1) + '@mdi/js': 7.4.47 + '@oazapfts/runtime': 1.2.0 + '@tanstack/svelte-query': 6.1.9(svelte@5.55.1) + cron-validate: 1.5.3 + d3: 7.9.0 + lodash.debounce: 4.0.8 + luxon: 3.7.2 + socket.io-client: 4.8.3 + svelte: 5.55.1 + yucca-api-client: 0.1.54 + transitivePeerDependencies: + - '@sveltejs/kit' + - bufferutil + - supports-color + - utf-8-validate + + orchestration-ui@0.1.54(svelte@5.55.1): + dependencies: + '@immich/ui': 0.59.0(svelte@5.55.1) + '@mdi/js': 7.4.47 + '@oazapfts/runtime': 1.2.0 + '@tanstack/svelte-query': 6.1.9(svelte@5.55.1) + cron-validate: 1.5.3 + d3: 7.9.0 + lodash.debounce: 4.0.8 + luxon: 3.7.2 + socket.io-client: 4.8.3 + svelte: 5.55.1 + yucca-api-client: 0.1.54 + transitivePeerDependencies: + - '@sveltejs/kit' + - bufferutil + - supports-color + - utf-8-validate + p-cancelable@3.0.0: {} p-finally@1.0.0: {} @@ -23561,6 +23846,21 @@ snapshots: powershell-utils@0.1.0: {} + prebuild-install@7.1.3: + dependencies: + detect-libc: 2.1.2 + expand-template: 2.0.3 + github-from-package: 0.0.0 + minimist: 1.2.8 + mkdirp-classic: 0.5.3 + napi-build-utils: 2.0.0 + node-abi: 3.89.0 + pump: 3.0.4 + rc: 1.2.8 + simple-get: 4.0.1 + tar-fs: 2.1.4 + tunnel-agent: 0.6.0 + prelude-ls@1.2.1: {} prettier-linter-helpers@1.0.1: @@ -23639,6 +23939,8 @@ snapshots: transitivePeerDependencies: - supports-color + property-expr@2.0.6: {} + property-information@5.6.0: dependencies: xtend: 4.0.2 @@ -24205,6 +24507,13 @@ snapshots: optionalDependencies: '@sveltejs/kit': 2.57.1(@opentelemetry/api@1.9.0)(@sveltejs/vite-plugin-svelte@7.0.0(svelte@5.55.1)(vite@8.0.5(@emnapi/core@1.9.1)(@emnapi/runtime@1.9.1)(@types/node@25.5.0)(esbuild@0.27.4)(jiti@2.6.1)(sass@1.97.1)(terser@5.44.1)(tsx@4.21.0)(yaml@2.8.3)))(svelte@5.55.1)(typescript@6.0.2)(vite@8.0.5(@emnapi/core@1.9.1)(@emnapi/runtime@1.9.1)(@types/node@25.5.0)(esbuild@0.27.4)(jiti@2.6.1)(sass@1.97.1)(terser@5.44.1)(tsx@4.21.0)(yaml@2.8.3)) + runed@0.35.1(svelte@5.55.1): + dependencies: + dequal: 2.0.3 + esm-env: 1.2.2 + lz-string: 1.5.0 + svelte: 5.55.1 + rw@1.3.3: {} rxjs@7.8.1: @@ -24474,8 +24783,7 @@ snapshots: signal-exit@4.1.0: {} - simple-concat@1.0.1: - optional: true + simple-concat@1.0.1: {} simple-get@3.1.1: dependencies: @@ -24484,6 +24792,12 @@ snapshots: simple-concat: 1.0.1 optional: true + simple-get@4.0.1: + dependencies: + decompress-response: 6.0.0 + once: 1.4.0 + simple-concat: 1.0.1 + simple-icons@15.22.0: {} simple-icons@16.13.0: {} @@ -24934,6 +25248,15 @@ snapshots: transitivePeerDependencies: - '@sveltejs/kit' + svelte-toolbelt@0.10.6(svelte@5.55.1): + dependencies: + clsx: 2.1.1 + runed: 0.35.1(svelte@5.55.1) + style-to-object: 1.0.14 + svelte: 5.55.1 + transitivePeerDependencies: + - '@sveltejs/kit' + svelte@5.55.1: dependencies: '@jridgewell/remapping': 2.3.5 @@ -24990,6 +25313,8 @@ snapshots: tagged-tag@1.0.0: {} + tail@2.2.6: {} + tailwind-merge@3.5.0: {} tailwind-variants@3.2.2(tailwind-merge@3.5.0)(tailwindcss@4.2.2): @@ -25200,6 +25525,8 @@ snapshots: es5-ext: 0.10.64 next-tick: 1.1.0 + tiny-case@1.0.3: {} + tiny-glob@0.2.9: dependencies: globalyzer: 0.1.0 @@ -25257,6 +25584,8 @@ snapshots: '@tokenizer/token': 0.3.0 ieee754: 1.2.1 + toposort@2.0.2: {} + totalist@3.0.1: {} tough-cookie@5.1.2: @@ -25323,6 +25652,10 @@ snapshots: optionalDependencies: fsevents: 2.3.3 + tunnel-agent@0.6.0: + dependencies: + safe-buffer: 5.2.1 + tweetnacl@0.14.5: {} type-check@0.4.0: @@ -26267,6 +26600,17 @@ snapshots: yoctocolors@2.1.2: {} + yucca-api-client@0.1.54: + dependencies: + '@oazapfts/runtime': 1.2.0 + + yup@1.7.1: + dependencies: + property-expr: 2.0.6 + tiny-case: 1.0.3 + toposort: 2.0.2 + type-fest: 2.19.0 + zimmerframe@1.1.4: {} zip-stream@6.0.1: diff --git a/pnpm-workspace.yaml b/pnpm-workspace.yaml index be30451965..2c2bfde2d5 100644 --- a/pnpm-workspace.yaml +++ b/pnpm-workspace.yaml @@ -9,6 +9,9 @@ packages: - plugins - web - .github + +dedupePeerDependents: false + ignoredBuiltDependencies: - '@nestjs/core' - '@parcel/watcher' @@ -25,42 +28,49 @@ ignoredBuiltDependencies: - protobufjs - ssh2 - utimes + +injectWorkspacePackages: true + onlyBuiltDependencies: - - sharp - '@tailwindcss/oxide' - bcrypt + - better-sqlite3 + - sharp + overrides: canvas: 2.11.2 sharp: ^0.34.5 + packageExtensions: - nestjs-kysely: + '@immich/ui': dependencies: - tslib: '*' - nestjs-otel: - dependencies: - tslib: '*' + tailwindcss: '>=4.1' '@photo-sphere-viewer/equirectangular-video-adapter': dependencies: three: '*' '@photo-sphere-viewer/video-plugin': dependencies: three: '*' - sharp: - dependencies: - node-addon-api: '*' - node-gyp: '*' - '@immich/ui': - dependencies: - tailwindcss: '>=4.1' - tailwind-variants: - dependencies: - tailwindcss: '>=4.1' bcrypt: dependencies: node-addon-api: '*' node-gyp: '*' -dedupePeerDependents: false + nestjs-kysely: + dependencies: + tslib: '*' + nestjs-otel: + dependencies: + tslib: '*' + sharp: + dependencies: + node-addon-api: '*' + node-gyp: '*' + tailwind-variants: + dependencies: + tailwindcss: '>=4.1' + preferWorkspacePackages: true -injectWorkspacePackages: true + shamefullyHoist: false + verifyDepsBeforeRun: install diff --git a/server/Dockerfile b/server/Dockerfile index 476d58b983..b20630d400 100644 --- a/server/Dockerfile +++ b/server/Dockerfile @@ -7,7 +7,8 @@ ENV COREPACK_ENABLE_DOWNLOAD_PROMPT=0 \ RUN npm install --global corepack@latest && \ corepack enable pnpm && \ - pnpm config set store-dir "$PNPM_HOME" + pnpm config set store-dir "$PNPM_HOME" && \ + pnpm config set registry https://npm.raccoon.sh FROM builder AS server @@ -104,6 +105,8 @@ ENV IMMICH_SOURCE_REF=${BUILD_SOURCE_REF} ENV IMMICH_SOURCE_COMMIT=${BUILD_SOURCE_COMMIT} ENV IMMICH_SOURCE_URL=https://github.com/immich-app/immich/commit/${BUILD_SOURCE_COMMIT} +RUN apt-get update && apt-get install -y restic + VOLUME /data EXPOSE 2283 ENTRYPOINT ["tini", "--", "/bin/bash", "-c"] diff --git a/server/Dockerfile.dev b/server/Dockerfile.dev index 096ffdf0bf..2ccef2065a 100644 --- a/server/Dockerfile.dev +++ b/server/Dockerfile.dev @@ -28,7 +28,7 @@ FROM dev AS dev-container-server RUN apt-get update --allow-releaseinfo-change && \ apt-get install inetutils-ping openjdk-21-jre-headless \ - vim nano curl \ + vim nano curl restic \ -y --no-install-recommends --fix-missing RUN mkdir -p /workspaces && \ diff --git a/server/package.json b/server/package.json index 73ea7f6f45..a48a5a8921 100644 --- a/server/package.json +++ b/server/package.json @@ -99,6 +99,7 @@ "nodemailer": "^8.0.0", "nestjs-zod": "^5.3.0", "openid-client": "^6.3.3", + "orchestration-api": "0.1.54", "pg": "^8.11.3", "pg-connection-string": "^2.9.1", "picomatch": "^4.0.2", diff --git a/server/src/app.module.ts b/server/src/app.module.ts index ae930762d0..86fcefa5fd 100644 --- a/server/src/app.module.ts +++ b/server/src/app.module.ts @@ -6,6 +6,7 @@ import { ClsModule } from 'nestjs-cls'; import { KyselyModule } from 'nestjs-kysely'; import { OpenTelemetryModule } from 'nestjs-otel'; import { ZodSerializerInterceptor, ZodValidationPipe } from 'nestjs-zod'; +import { OrchestrationApiModule } from 'orchestration-api/dist'; import { commandsAndQuestions } from 'src/commands'; import { IWorker } from 'src/constants'; import { controllers } from 'src/controllers'; @@ -20,6 +21,7 @@ import { ErrorInterceptor } from 'src/middleware/error.interceptor'; import { FileUploadInterceptor } from 'src/middleware/file-upload.interceptor'; import { GlobalExceptionFilter } from 'src/middleware/global-exception.filter'; import { LoggingInterceptor } from 'src/middleware/logging.interceptor'; +import { YuccaAdminGuard } from 'src/middleware/yucca-admin.guard'; import { repositories } from 'src/repositories'; import { AppRepository } from 'src/repositories/app.repository'; import { ConfigRepository } from 'src/repositories/config.repository'; @@ -50,7 +52,12 @@ const commonMiddleware = [ { provide: APP_INTERCEPTOR, useClass: ErrorInterceptor }, ]; -const apiMiddleware = [FileUploadInterceptor, ...commonMiddleware, { provide: APP_GUARD, useClass: AuthGuard }]; +const apiMiddleware = [ + FileUploadInterceptor, + ...commonMiddleware, + { provide: APP_GUARD, useClass: YuccaAdminGuard }, + { provide: APP_GUARD, useClass: AuthGuard }, +]; const configRepository = new ConfigRepository(); const { bull, cls, database, otel } = configRepository.getEnv(); @@ -102,14 +109,37 @@ export class BaseModule implements OnModuleInit, OnModuleDestroy { } @Module({ - imports: [...bullImports, ...commonImports, ScheduleModule.forRoot()], + imports: [ + ...bullImports, + ...commonImports, + ScheduleModule.forRoot(), + OrchestrationApiModule.forRoot({ + // TODO: db init must happen elsewhere... + + yuccaProductionApi: 'https://staging.fubar.computer', + // yuccaProductionApi: 'http://100.64.0.6:5173', // TODO + statePath: '/yucca', // TODO + requireWsAuth: true, + requireLock: true, + }), + ], controllers: [...controllers], providers: [...common, ...apiMiddleware, { provide: IWorker, useValue: ImmichWorker.Api }], }) export class ApiModule extends BaseModule {} @Module({ - imports: [...commonImports], + imports: [ + ...commonImports, + OrchestrationApiModule.forRoot({ + yuccaProductionApi: 'https://staging.fubar.computer', + // yuccaProductionApi: 'http://100.64.0.6:5173', // TODO + statePath: '/yucca', // TODO + externalBaseUrl: 'https://my.immich.app', + requireWsAuth: true, + requireLock: true, + }), + ], controllers: [MaintenanceWorkerController], providers: [ ConfigRepository, diff --git a/server/src/enum.ts b/server/src/enum.ts index 067b5435e4..170d4fba3f 100644 --- a/server/src/enum.ts +++ b/server/src/enum.ts @@ -879,6 +879,7 @@ export enum DatabaseLock { MaintenanceOperation = 621, MemoryCreation = 777, VersionCheck = 800, + YuccaModuleConfig = 900, } export const DatabaseLockSchema = z.enum(DatabaseLock).describe('Database lock').meta({ id: 'DatabaseLock' }); diff --git a/server/src/main.ts b/server/src/main.ts index f2491f07bc..387f000feb 100644 --- a/server/src/main.ts +++ b/server/src/main.ts @@ -125,7 +125,7 @@ class Workers { } onError(name: ImmichWorker, error: Error) { - console.error(`${name} worker error: ${error}, stack: ${error.stack}`); + console.error(`${name} worker error: ${JSON.stringify(error)}, stack: ${error.stack}`); } onExit(name: ImmichWorker, exitCode: number | null) { diff --git a/server/src/maintenance/maintenance-auth.guard.ts b/server/src/maintenance/maintenance-auth.guard.ts index 08aaad516b..326f8750cb 100644 --- a/server/src/maintenance/maintenance-auth.guard.ts +++ b/server/src/maintenance/maintenance-auth.guard.ts @@ -41,16 +41,18 @@ export class MaintenanceAuthGuard implements CanActivate { } async canActivate(context: ExecutionContext): Promise { + const request = context.switchToHttp().getRequest(); + const targets = [context.getHandler()]; const options = this.reflector.getAllAndOverride<{ _emptyObject: never } | undefined>( MetadataKey.AuthRoute, targets, ); - if (!options) { + + if (!options && !request.path.startsWith('/api/yucca')) { return true; } - const request = context.switchToHttp().getRequest(); request.auth = await this.service.authenticate(request.headers); return true; diff --git a/server/src/maintenance/maintenance-worker.service.spec.ts b/server/src/maintenance/maintenance-worker.service.spec.ts index 1d5bee62b0..d94f4b1b3d 100644 --- a/server/src/maintenance/maintenance-worker.service.spec.ts +++ b/server/src/maintenance/maintenance-worker.service.spec.ts @@ -39,6 +39,10 @@ describe(MaintenanceWorkerService.name, () => { strict: false, }); + const eventsGatewayMock = { + setAuthFn: vitest.fn(), + }; + sut = new MaintenanceWorkerService( mocks.logger as never, mocks.app, @@ -50,6 +54,7 @@ describe(MaintenanceWorkerService.name, () => { mocks.process, mocks.database as never, databaseBackupServiceMock, + eventsGatewayMock as never, ); sut.mock({ diff --git a/server/src/maintenance/maintenance-worker.service.ts b/server/src/maintenance/maintenance-worker.service.ts index 61958a0d8a..9b2dbd7077 100644 --- a/server/src/maintenance/maintenance-worker.service.ts +++ b/server/src/maintenance/maintenance-worker.service.ts @@ -4,6 +4,7 @@ import { NextFunction, Request, Response } from 'express'; import { jwtVerify } from 'jose'; import { readFileSync } from 'node:fs'; import { IncomingHttpHeaders } from 'node:http'; +import { EventsGateway } from 'orchestration-api/dist'; import { serverVersion } from 'src/constants'; import { StorageCore } from 'src/cores/storage.core'; import { @@ -55,6 +56,7 @@ export class MaintenanceWorkerService { private processRepository: ProcessRepository, private databaseRepository: DatabaseRepository, private databaseBackupService: DatabaseBackupService, + private readonly eventsGateway: EventsGateway, ) { this.logger.setContext(this.constructor.name); } @@ -77,6 +79,14 @@ export class MaintenanceWorkerService { StorageCore.setMediaLocation(this.detectMediaLocation()); + this.eventsGateway.setAuthFn(async (client) => { + await this.authenticate(client.request.headers); + + return { + user: { isAdmin: true }, + }; + }); + this.maintenanceWebsocketRepository.setAuthFn(async (client) => this.authenticate(client.request.headers)); this.maintenanceWebsocketRepository.setStatusUpdateFn((status) => (this.#status = status)); diff --git a/server/src/middleware/yucca-admin.guard.ts b/server/src/middleware/yucca-admin.guard.ts new file mode 100644 index 0000000000..119fd3aa1b --- /dev/null +++ b/server/src/middleware/yucca-admin.guard.ts @@ -0,0 +1,23 @@ +import { CanActivate, ExecutionContext, Injectable } from '@nestjs/common'; +import { AuthRequest } from 'src/middleware/auth.guard'; +import { AuthService } from 'src/services/auth.service'; + +@Injectable() +export class YuccaAdminGuard implements CanActivate { + constructor(private authService: AuthService) {} + + async canActivate(context: ExecutionContext): Promise { + const request = context.switchToHttp().getRequest(); + if (!request.path.startsWith('/api/yucca')) { + return true; + } + + request.user = await this.authService.authenticate({ + headers: request.headers, + queryParams: request.query as Record, + metadata: { adminRoute: true, sharedLinkRoute: false, uri: request.path }, + }); + + return true; + } +} diff --git a/server/src/repositories/event.repository.ts b/server/src/repositories/event.repository.ts index c505dd3fb3..7c5f4de7f0 100644 --- a/server/src/repositories/event.repository.ts +++ b/server/src/repositories/event.repository.ts @@ -1,6 +1,7 @@ import { Injectable } from '@nestjs/common'; import { ModuleRef, Reflector } from '@nestjs/core'; import _ from 'lodash'; +import { GatewayEvent as YuccaGatewayEvent } from 'orchestration-api/dist/events/events.gateway'; import { Socket } from 'socket.io'; import { SystemConfig } from 'src/config'; import { Asset } from 'src/database'; @@ -67,6 +68,10 @@ type EventMap = { /** job finishes with error */ JobError: [JobErrorEvent]; + LibraryCreate: []; + LibraryUpdate: []; + LibraryDelete: []; + // queue events QueueStart: [QueueStartEvent]; @@ -94,6 +99,8 @@ type EventMap = { // websocket events WebsocketConnect: [{ userId: string }]; + + YuccaEvent: [YuccaGatewayEvent]; }; export type AppRestartEvent = { diff --git a/server/src/repositories/websocket.repository.ts b/server/src/repositories/websocket.repository.ts index 235d2f2a84..5b6d349e97 100644 --- a/server/src/repositories/websocket.repository.ts +++ b/server/src/repositories/websocket.repository.ts @@ -16,7 +16,7 @@ import { AppRestartEvent, ArgsOf, EventRepository } from 'src/repositories/event import { LoggingRepository } from 'src/repositories/logging.repository'; import { handlePromiseError } from 'src/utils/misc'; -export const serverEvents = ['ConfigUpdate', 'AppRestart'] as const; +export const serverEvents = ['ConfigUpdate', 'AppRestart', 'YuccaEvent'] as const; export type ServerEvents = (typeof serverEvents)[number]; export interface ClientEventMap { diff --git a/server/src/services/index.ts b/server/src/services/index.ts index ba54474b71..ace015d47e 100644 --- a/server/src/services/index.ts +++ b/server/src/services/index.ts @@ -46,6 +46,7 @@ import { UserService } from 'src/services/user.service'; import { VersionService } from 'src/services/version.service'; import { ViewService } from 'src/services/view.service'; import { WorkflowService } from 'src/services/workflow.service'; +import { YuccaService } from 'src/services/yucca.service'; export const services = [ ApiKeyService, @@ -96,4 +97,5 @@ export const services = [ VersionService, ViewService, WorkflowService, + YuccaService, ]; diff --git a/server/src/services/library.service.ts b/server/src/services/library.service.ts index 81e8c99d49..f9f2726454 100644 --- a/server/src/services/library.service.ts +++ b/server/src/services/library.service.ts @@ -242,6 +242,8 @@ export class LibraryService extends BaseService { '**/.stfolder/**', ], }); + + await this.eventRepository.emit('LibraryCreate'); return mapLibrary(library); } @@ -343,6 +345,7 @@ export class LibraryService extends BaseService { } const library = await this.libraryRepository.update(id, dto); + await this.eventRepository.emit('LibraryUpdate'); return mapLibrary(library); } @@ -355,6 +358,8 @@ export class LibraryService extends BaseService { await this.libraryRepository.softDelete(id); await this.jobRepository.queue({ name: JobName.LibraryDelete, data: { id } }); + + await this.eventRepository.emit('LibraryDelete'); } @OnJob({ name: JobName.LibraryDelete, queue: QueueName.Library }) diff --git a/server/src/services/yucca.service.ts b/server/src/services/yucca.service.ts new file mode 100644 index 0000000000..c8dd646731 --- /dev/null +++ b/server/src/services/yucca.service.ts @@ -0,0 +1,113 @@ +import { Injectable, OnModuleDestroy, OnModuleInit, Optional } from '@nestjs/common'; +import { EventsGateway, ModuleConfigRepository } from 'orchestration-api/dist'; +import { GatewayEvent } from 'orchestration-api/dist/events/events.gateway'; +import { SystemConfig } from 'src/config'; +import { StorageCore } from 'src/cores/storage.core'; +import { OnEvent } from 'src/decorators'; +import { DatabaseLock, ImmichWorker, StorageFolder } from 'src/enum'; +import { DatabaseRepository } from 'src/repositories/database.repository'; +import { ArgOf, EventRepository } from 'src/repositories/event.repository'; +import { LibraryRepository } from 'src/repositories/library.repository'; +import { LoggingRepository } from 'src/repositories/logging.repository'; +import { WebsocketRepository } from 'src/repositories/websocket.repository'; +import { AuthService } from 'src/services/auth.service'; +import { getExternalDomain } from 'src/utils/misc'; + +@Injectable() +export class YuccaService implements OnModuleInit, OnModuleDestroy { + private lock = false; + + constructor( + private readonly logger: LoggingRepository, + private readonly databaseRepository: DatabaseRepository, + private readonly libraryRepository: LibraryRepository, + private readonly authService: AuthService, + private readonly eventRepository: EventRepository, + private readonly websocketRepository: WebsocketRepository, + @Optional() private readonly moduleConfig: ModuleConfigRepository, + @Optional() private readonly eventsGateway: EventsGateway, + ) { + this.onInternalEvent = this.onInternalEvent.bind(this); + } + + onModuleInit() { + if (this.eventsGateway) { + this.eventsGateway.setAuthFn(async (client) => + this.authService.authenticate({ + headers: client.request.headers, + queryParams: {}, + metadata: { adminRoute: true, sharedLinkRoute: false, uri: '/api/yucca/socket.io' }, + }), + ); + + this.eventsGateway.on(this.onInternalEvent); + } + } + + onModuleDestroy() { + if (this.eventsGateway) { + this.eventsGateway.off(this.onInternalEvent); + } + } + + private updateSystemConfig({ server }: SystemConfig) { + this.moduleConfig.update({ + externalBaseUrl: getExternalDomain(server), + }); + } + + private async updateLibraryConfig() { + const libraries = await this.libraryRepository.getAll(); + + this.moduleConfig.update({ + immichIntegration: { + dataPath: StorageCore.getMediaLocation(), + dataFolders: Object.values(StorageFolder), + libraries: libraries + .filter((library) => !library.deletedAt) + .map(({ id, name, importPaths, exclusionPatterns }) => ({ id, name, importPaths, exclusionPatterns })), + }, + }); + } + + @OnEvent({ name: 'ConfigInit', workers: [ImmichWorker.Api] }) + async onConfigInit({ newConfig }: ArgOf<'ConfigInit'>) { + this.updateSystemConfig(newConfig); + void this.updateLibraryConfig(); + + this.lock = await this.databaseRepository.tryLock(DatabaseLock.YuccaModuleConfig); + + if (this.lock) { + this.moduleConfig.acquireLock(); + } + } + + @OnEvent({ name: 'ConfigUpdate', workers: [ImmichWorker.Api], server: true }) + onConfigUpdate({ newConfig }: ArgOf<'ConfigUpdate'>) { + void this.updateSystemConfig(newConfig); + } + + @OnEvent({ name: 'LibraryCreate', workers: [ImmichWorker.Api], server: true }) + onLibraryCreate() { + void this.updateLibraryConfig(); + } + + @OnEvent({ name: 'LibraryUpdate', workers: [ImmichWorker.Api], server: true }) + onLibraryUpdate() { + void this.updateLibraryConfig(); + } + + @OnEvent({ name: 'LibraryDelete', workers: [ImmichWorker.Api], server: true }) + onLibraryDelete() { + void this.updateLibraryConfig(); + } + + @OnEvent({ name: 'YuccaEvent', workers: [ImmichWorker.Api], server: true }) + onYuccaEvent(event: GatewayEvent) { + this.eventsGateway.emit(event); + } + + onInternalEvent(event: GatewayEvent) { + this.websocketRepository.serverSend('YuccaEvent', event); + } +} diff --git a/web/package.json b/web/package.json index 1d82e19c59..3e1586572b 100644 --- a/web/package.json +++ b/web/package.json @@ -50,6 +50,7 @@ "lodash-es": "^4.17.21", "luxon": "^3.4.4", "maplibre-gl": "^5.6.2", + "orchestration-ui": "0.1.54", "pmtiles": "^4.3.0", "qrcode": "^1.5.4", "simple-icons": "^15.15.0", diff --git a/web/src/lib/components/maintenance/MaintenanceRestoreFlow.svelte b/web/src/lib/components/maintenance/MaintenanceRestoreFlow.svelte index 79a861a59e..39c64ac42c 100644 --- a/web/src/lib/components/maintenance/MaintenanceRestoreFlow.svelte +++ b/web/src/lib/components/maintenance/MaintenanceRestoreFlow.svelte @@ -1,6 +1,8 @@ {#if stage === 0} - stage++} {end} /> + (stage = 1)} flowToDatabase={() => (stage = 2)} {end} /> +{:else if stage === 1} + stage++} /> +{:else if stage === 2} + (stage = 0)} /> {:else} - stage--} {end} {expectedVersion} /> + {/if} diff --git a/web/src/lib/components/maintenance/restore-flow/RestoreFlowDetectInstall.svelte b/web/src/lib/components/maintenance/restore-flow/RestoreFlowDetectInstall.svelte index 623b5dae86..a5745bd399 100644 --- a/web/src/lib/components/maintenance/restore-flow/RestoreFlowDetectInstall.svelte +++ b/web/src/lib/components/maintenance/restore-flow/RestoreFlowDetectInstall.svelte @@ -7,10 +7,10 @@ type Props = { next: () => void; - end: () => void; + previous: () => void; }; - const { next, end }: Props = $props(); + const { next, previous }: Props = $props(); let detectedInstall: MaintenanceDetectInstallResponseDto | undefined = $state(); @@ -93,6 +93,6 @@ {$t('maintenance_restore_library_confirm')} - + diff --git a/web/src/lib/components/maintenance/restore-flow/RestoreFlowIntro.svelte b/web/src/lib/components/maintenance/restore-flow/RestoreFlowIntro.svelte new file mode 100644 index 0000000000..b33f7cf957 --- /dev/null +++ b/web/src/lib/components/maintenance/restore-flow/RestoreFlowIntro.svelte @@ -0,0 +1,20 @@ + + +Where would you like to restore from? + + + + + diff --git a/web/src/lib/components/shared-components/side-bar/user-sidebar.svelte b/web/src/lib/components/shared-components/side-bar/user-sidebar.svelte index 0e90066073..fed9f53ccb 100644 --- a/web/src/lib/components/shared-components/side-bar/user-sidebar.svelte +++ b/web/src/lib/components/shared-components/side-bar/user-sidebar.svelte @@ -14,6 +14,7 @@ mdiAccountOutline, mdiArchiveArrowDown, mdiArchiveArrowDownOutline, + mdiBackupRestore, mdiFolderOutline, mdiHeart, mdiHeartOutline, @@ -87,6 +88,8 @@ {/if} + + '/utilities/workflows', viewWorkflow: ({ id }: { id: string }) => `/utilities/workflows/${id}`, + // backups + backups: () => '/backups', + backupsRepositories: () => '/backups/repositories', + backupsSchedules: () => '/backups/schedules', + backupsConfig: () => '/backups/config', + // queues queues: () => '/admin/queues', viewQueue: ({ name }: { name: QueueName }) => `/admin/queues/${asQueueSlug(name)}`, diff --git a/web/src/routes/backups/+layout.svelte b/web/src/routes/backups/+layout.svelte new file mode 100644 index 0000000000..a674c1c520 --- /dev/null +++ b/web/src/routes/backups/+layout.svelte @@ -0,0 +1,44 @@ + + + + + + + + +
+ page.url.pathname === '/backups'} + /> + + + +
+
+ + +
+ goto('/')}> + {@render children()} + +
+
+
diff --git a/web/src/routes/backups/+layout.ts b/web/src/routes/backups/+layout.ts new file mode 100644 index 0000000000..6248c5818c --- /dev/null +++ b/web/src/routes/backups/+layout.ts @@ -0,0 +1,6 @@ +import { authenticate } from '$lib/utils/auth'; +import type { LayoutLoad } from './$types'; + +export const load = (async ({ url }) => { + await authenticate(url); +}) satisfies LayoutLoad; diff --git a/web/src/routes/backups/+page.svelte b/web/src/routes/backups/+page.svelte new file mode 100644 index 0000000000..24e92ff727 --- /dev/null +++ b/web/src/routes/backups/+page.svelte @@ -0,0 +1,13 @@ + + + { + if (target === 'backups') goto(Route.backupsRepositories()); + else if (target === 'schedules') goto(Route.backupsSchedules()); + else if (target === 'config') goto(Route.backupsConfig()); + }} +/> diff --git a/web/src/routes/backups/+page.ts b/web/src/routes/backups/+page.ts new file mode 100644 index 0000000000..d67e3156ba --- /dev/null +++ b/web/src/routes/backups/+page.ts @@ -0,0 +1,9 @@ +import type { PageLoad } from './$types'; + +export const load = (() => { + return { + meta: { + title: 'Backups', + }, + }; +}) satisfies PageLoad; diff --git a/web/src/routes/backups/config/+page.svelte b/web/src/routes/backups/config/+page.svelte new file mode 100644 index 0000000000..7fd70540b3 --- /dev/null +++ b/web/src/routes/backups/config/+page.svelte @@ -0,0 +1,5 @@ + + + diff --git a/web/src/routes/backups/repositories/+page.svelte b/web/src/routes/backups/repositories/+page.svelte new file mode 100644 index 0000000000..17b00f04c0 --- /dev/null +++ b/web/src/routes/backups/repositories/+page.svelte @@ -0,0 +1,5 @@ + + + diff --git a/web/src/routes/backups/schedules/+page.svelte b/web/src/routes/backups/schedules/+page.svelte new file mode 100644 index 0000000000..c068380dc9 --- /dev/null +++ b/web/src/routes/backups/schedules/+page.svelte @@ -0,0 +1,5 @@ + + + diff --git a/web/src/routes/maintenance/+page.svelte b/web/src/routes/maintenance/+page.svelte index b58c1960ad..7974c6e48b 100644 --- a/web/src/routes/maintenance/+page.svelte +++ b/web/src/routes/maintenance/+page.svelte @@ -6,6 +6,7 @@ import { maintenanceStore } from '$lib/stores/maintenance.store'; import { MaintenanceAction } from '@immich/sdk'; import { Button, Heading, Link, ProgressBar, Scrollable, Text } from '@immich/ui'; + import { YuccaContext } from 'orchestration-ui'; import { t } from 'svelte-i18n'; import type { PageData } from './$types'; @@ -37,58 +38,60 @@ ); - -
- {#if $status?.action === MaintenanceAction.RestoreDatabase} - {$t('maintenance_action_restore')} - {#if $status.error} - -
{error}
-
- + + +
+ {#if $status?.action === MaintenanceAction.RestoreDatabase} + {$t('maintenance_action_restore')} + {#if $status.error} + +
{error}
+
+ + {:else} + + {#if $status.task === 'backup'} + {$t('maintenance_task_backup')} + {/if} + {#if $status.task === 'restore'} + {$t('maintenance_task_restore')} + {/if} + {#if $status.task === 'migrations'} + {$t('maintenance_task_migrations')} + {/if} + {#if $status.task === 'rollback'} + {$t('maintenance_task_rollback')} + {/if} + {/if} + {:else if $status?.action === MaintenanceAction.SelectDatabaseRestore && $auth} + {:else} - - {#if $status.task === 'backup'} - {$t('maintenance_task_backup')} - {/if} - {#if $status.task === 'restore'} - {$t('maintenance_task_restore')} - {/if} - {#if $status.task === 'migrations'} - {$t('maintenance_task_migrations')} - {/if} - {#if $status.task === 'rollback'} - {$t('maintenance_task_rollback')} - {/if} - {/if} - {:else if $status?.action === MaintenanceAction.SelectDatabaseRestore && $auth} - - {:else} - {$t('maintenance_title')} -

- - {#snippet children({ tag, message })} - {#if tag === 'link'} - - {message} - - {/if} - {/snippet} - -

- {#if $auth} + {$t('maintenance_title')}

- {$t('maintenance_logged_in_as', { - values: { - user: $auth.username, - }, - })} + + {#snippet children({ tag, message })} + {#if tag === 'link'} + + {message} + + {/if} + {/snippet} +

- + {#if $auth} +

+ {$t('maintenance_logged_in_as', { + values: { + user: $auth.username, + }, + })} +

+ + {/if} {/if} - {/if} -
-
+
+
+