diff --git a/e2e/package.json b/e2e/package.json index 77003c03d7..0fc67b2a05 100644 --- a/e2e/package.json +++ b/e2e/package.json @@ -26,6 +26,7 @@ "devDependencies": { "@eslint/js": "^10.0.0", "@faker-js/faker": "^10.1.0", + "@futo-org/backups-orchestrator-ui": "0.1.72", "@immich/cli": "workspace:*", "@immich/e2e-auth-server": "workspace:*", "@immich/sdk": "workspace:*", 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..9c9c151e25 --- /dev/null +++ b/e2e/src/specs/maintenance/server/yucca-backups.e2e-spec.ts @@ -0,0 +1,385 @@ +import * as sdk from '@futo-org/backups-orchestrator-ui/sdk'; +import { LoginResponseDto, StorageFolder } from '@immich/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(64), + }, + 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(64), + }, + 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/specs/maintenance/web/yucca-backups.e2e-spec.ts b/e2e/src/specs/maintenance/web/yucca-backups.e2e-spec.ts new file mode 100644 index 0000000000..c6b5c2d6e6 --- /dev/null +++ b/e2e/src/specs/maintenance/web/yucca-backups.e2e-spec.ts @@ -0,0 +1,141 @@ +import { LoginResponseDto, confirmRecoveryKey, importRecoveryKey, resetOrchestrator } from '@immich/sdk'; +import { expect, test } from '@playwright/test'; +import { io, type Socket } from 'socket.io-client'; +import { asBearerAuth, baseUrl, utils } from 'src/utils'; + +test.describe.configure({ mode: 'serial' }); + +test.describe('Yucca Backups', () => { + let admin: LoginResponseDto; + let socket: Socket; + + const waitForTaskEnd = () => + new Promise((resolve) => { + const listener = (msg: string) => { + try { + const payload = JSON.parse(msg); + if (payload.type === 'TaskEnd') { + socket.offAny(listener); + resolve(); + } + } catch { + // no-op + } + }; + socket.onAny(listener); + }); + + test.beforeAll(async () => { + utils.initSdk(); + await utils.resetDatabase(); + admin = await utils.adminSetup(); + + const headers = asBearerAuth(admin.accessToken); + await resetOrchestrator({ headers }); + await importRecoveryKey({ importRecoveryKeyRequest: { recoveryKey: '0'.repeat(64) } }, { headers }); + await confirmRecoveryKey({ headers }); + await utils.mkdir('/local-backend'); + + socket = io(baseUrl, { + path: '/api/yucca/socket.io', + transports: ['websocket'], + extraHeaders: headers, + forceNew: true, + }); + await new Promise((resolve) => socket.on('connect', () => resolve())); + }); + + test.afterAll(async () => { + socket?.close(); + }); + + test('onboarding configures a local backend', async ({ context, page }) => { + test.setTimeout(30_000); + await utils.setAuthCookies(context, admin.accessToken); + + await page.goto('/backups'); + + const dialog = page.getByRole('dialog'); + await expect(dialog.filter({ hasText: 'Backup options' })).toBeVisible(); + await dialog.getByText('Local Folder').click(); + + await expect(dialog.filter({ hasText: 'Create local backend' })).toBeVisible(); + await dialog.getByLabel('Path').fill('/local-backend'); + await dialog.getByRole('button', { name: 'Save' }).click(); + + await expect(dialog.filter({ hasText: 'Configure Your Immich Backup' })).toBeVisible(); + await dialog.getByRole('button', { name: 'Save' }).click(); + await expect(dialog).toHaveCount(0); + + await expect(page.getByRole('link', { name: 'Repositories' })).toBeVisible(); + }); + + test('manually triggers a backup and waits for completion', async ({ context, page }) => { + test.setTimeout(60_000); + await utils.setAuthCookies(context, admin.accessToken); + + await page.goto('/backups/repositories'); + const backupNow = page.getByRole('button', { name: 'Backup Now' }); + await expect(backupNow).toBeVisible(); + + const taskEnd = waitForTaskEnd(); + await backupNow.click(); + await expect(page.getByRole('dialog').filter({ hasText: 'Log Output' })).toBeVisible(); + + await taskEnd; + }); + + test('resets immich and restores from the local yucca backup', async ({ context, page }) => { + test.setTimeout(120_000); + await utils.setAuthCookies(context, admin.accessToken); + + await utils.resetBackups(admin.accessToken); + await utils.createBackup(admin.accessToken); + + await resetOrchestrator({ headers: asBearerAuth(admin.accessToken) }); + await utils.resetDatabase(); + + await page.goto('/'); + await page.getByRole('button', { name: 'Restore from backup' }).click(); + + try { + await page.waitForURL('/maintenance**'); + } catch { + await page.goto('/maintenance'); + await page.waitForURL('/maintenance**'); + } + + await page.getByRole('button', { name: 'FUTO Backups' }).click(); + + const dialog = page.getByRole('dialog'); + await expect(dialog.filter({ hasText: 'Import recovery key' })).toBeVisible(); + await dialog.getByLabel('Recovery Key').fill('0'.repeat(64)); + await dialog.getByRole('button', { name: 'Save' }).click(); + + await expect(dialog.filter({ hasText: 'Where would you like to restore from?' })).toBeVisible(); + await dialog.getByText('Local Folder').click(); + + await expect(dialog.filter({ hasText: 'Create local backend' })).toBeVisible(); + await dialog.getByLabel('Path').fill('/local-backend'); + await dialog.getByRole('button', { name: 'Save' }).click(); + + await expect(dialog.filter({ hasText: 'Select Restore Point' })).toBeVisible(); + await dialog.getByRole('button', { name: 'Select' }).first().click(); + + await expect(dialog.filter({ hasText: /Restore from/ })).toBeVisible(); + await dialog.getByRole('button', { name: 'Restore' }).first().click(); + + await expect(dialog.filter({ hasText: 'Confirm restore from snapshot' })).toBeVisible(); + await dialog.getByRole('button', { name: 'Restore' }).click(); + + await expect(dialog.filter({ hasText: 'Restoring' })).toBeVisible(); + await expect(dialog.filter({ hasText: 'Restoring' })).toBeHidden({ timeout: 60_000 }); + + 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(); + + await page.waitForURL('/maintenance?**'); + await page.waitForURL('/photos', { timeout: 90_000 }); + }); +}); diff --git a/e2e/src/utils.ts b/e2e/src/utils.ts index 7e51b40f63..a85bc30287 100644 --- a/e2e/src/utils.ts +++ b/e2e/src/utils.ts @@ -30,6 +30,7 @@ import { createUserAdmin, deleteAssets, deleteDatabaseBackup, + deleteLibrary, getAssetInfo, getConfig, getConfigDefaults, @@ -460,6 +461,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) }), @@ -563,6 +566,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/e2e/test-assets b/e2e/test-assets index 6742055402..0eac5a3738 160000 --- a/e2e/test-assets +++ b/e2e/test-assets @@ -1 +1 @@ -Subproject commit 6742055402de1aa48f93d12ded7d18f4057f9d1f +Subproject commit 0eac5a37384c151be88381b41f9e28d8d59a4466 diff --git a/i18n/en.json b/i18n/en.json index dba0caf393..95bfc19610 100644 --- a/i18n/en.json +++ b/i18n/en.json @@ -1478,6 +1478,7 @@ "maintenance_end_error": "Failed to end maintenance mode.", "maintenance_logged_in_as": "Currently logged in as {user}", "maintenance_restore_from_backup": "Restore From Backup", + "maintenance_restore_latest_backup_description": "We'll restore your database from the most recent backup. You can also pick a different one.", "maintenance_restore_library": "Restore Your Library", "maintenance_restore_library_confirm": "If this looks correct, continue to restoring a backup!", "maintenance_restore_library_description": "Restoring Database", @@ -1490,6 +1491,10 @@ "maintenance_restore_library_hint_regenerate_later": "You can regenerate these later in settings", "maintenance_restore_library_hint_storage_template_missing_files": "Using storage template? You may be missing files", "maintenance_restore_library_loading": "Loading integrity checks and heuristics…", + "maintenance_restore_loading_backups": "Loading backups…", + "maintenance_restore_no_backups": "There are no database backups.", + "maintenance_restore_select_another": "Select another backup", + "maintenance_restore_upload_backup": "Upload a backup", "maintenance_task_backup": "Creating a backup of the existing database…", "maintenance_task_migrations": "Running database migrations…", "maintenance_task_restore": "Restoring the chosen backup…", diff --git a/mobile/openapi/README.md b/mobile/openapi/README.md index 23987073dd..8646820fed 100644 --- a/mobile/openapi/README.md +++ b/mobile/openapi/README.md @@ -118,6 +118,7 @@ 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* | [**oidcDeviceFlow**](doc//AuthApi.md#oidcdeviceflow) | **GET** /yucca/auth/oidc/device | *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 +137,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 @@ -144,6 +147,7 @@ Class | Method | HTTP request | Description *DeprecatedApi* | [**createPartnerDeprecated**](doc//DeprecatedApi.md#createpartnerdeprecated) | **POST** /partners/{id} | Create a partner *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} | Dismiss a duplicate group @@ -154,6 +158,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 @@ -188,6 +195,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 @@ -206,13 +218,35 @@ Class | Method | HTTP request | Description *PeopleApi* | [**updatePerson**](doc//PeopleApi.md#updateperson) | **PUT** /people/{id} | Update person *PluginsApi* | [**getPlugin**](doc//PluginsApi.md#getplugin) | **GET** /plugins/{id} | Retrieve a plugin *PluginsApi* | [**searchPluginMethods**](doc//PluginsApi.md#searchpluginmethods) | **GET** /plugins/methods | Retrieve plugin methods -*PluginsApi* | [**searchPluginTemplates**](doc//PluginsApi.md#searchplugintemplates) | **GET** /plugins/templates | Retrieve workflow templates *PluginsApi* | [**searchPlugins**](doc//PluginsApi.md#searchplugins) | **GET** /plugins | List all plugins *QueuesApi* | [**emptyQueue**](doc//QueuesApi.md#emptyqueue) | **DELETE** /queues/{name}/jobs | Empty a queue *QueuesApi* | [**getQueue**](doc//QueuesApi.md#getqueue) | **GET** /queues/{name} | Retrieve a queue *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* | [**deleteRepository**](doc//RepositoryApi.md#deleterepository) | **DELETE** /yucca/repository/{id} | +*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* | [**pruneRepository**](doc//RepositoryApi.md#prunerepository) | **POST** /yucca/repository/{id}/snapshots/prune | +*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* | [**getRun**](doc//RunHistoryApi.md#getrun) | **GET** /yucca/logs/{id} | +*RunHistoryApi* | [**logStreamSse**](doc//RunHistoryApi.md#logstreamsse) | **GET** /yucca/logs/{id}/stream | +*RunningTasksApi* | [**cancelTask**](doc//RunningTasksApi.md#canceltask) | **POST** /yucca/tasks/{parentId}/cancel | +*RunningTasksApi* | [**getRunningTasks**](doc//RunningTasksApi.md#getrunningtasks) | **GET** /yucca/tasks | +*ScheduleApi* | [**createSchedule**](doc//ScheduleApi.md#createschedule) | **POST** /yucca/schedule | +*ScheduleApi* | [**getSchedules**](doc//ScheduleApi.md#getschedules) | **GET** /yucca/schedule | +*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 @@ -323,6 +357,7 @@ Class | Method | HTTP request | Description ## Documentation For Models + - [ActiveScheduleItemDto](doc//ActiveScheduleItemDto.md) - [ActivityCreateDto](doc//ActivityCreateDto.md) - [ActivityResponseDto](doc//ActivityResponseDto.md) - [ActivityStatisticsResponseDto](doc//ActivityStatisticsResponseDto.md) @@ -389,6 +424,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) @@ -398,15 +437,20 @@ Class | Method | HTTP request | Description - [CastUpdate](doc//CastUpdate.md) - [ChangePasswordDto](doc//ChangePasswordDto.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) - [DatabaseBackupListResponseDto](doc//DatabaseBackupListResponseDto.md) + - [DeviceFlowResponseDto](doc//DeviceFlowResponseDto.md) - [DownloadArchiveDto](doc//DownloadArchiveDto.md) - [DownloadArchiveInfo](doc//DownloadArchiveInfo.md) - [DownloadInfoDto](doc//DownloadInfoDto.md) @@ -422,16 +466,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) @@ -472,6 +528,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) @@ -492,8 +549,6 @@ Class | Method | HTTP request | Description - [PlacesResponseDto](doc//PlacesResponseDto.md) - [PluginMethodResponseDto](doc//PluginMethodResponseDto.md) - [PluginResponseDto](doc//PluginResponseDto.md) - - [PluginTemplateResponseDto](doc//PluginTemplateResponseDto.md) - - [PluginTemplateStepResponseDto](doc//PluginTemplateStepResponseDto.md) - [PurchaseResponse](doc//PurchaseResponse.md) - [PurchaseUpdate](doc//PurchaseUpdate.md) - [QueueCommand](doc//QueueCommand.md) @@ -513,8 +568,35 @@ 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) + - [RetentionPolicyDto](doc//RetentionPolicyDto.md) - [ReverseGeocodingStateResponseDto](doc//ReverseGeocodingStateResponseDto.md) - [RotateParameters](doc//RotateParameters.md) + - [RunDto](doc//RunDto.md) + - [RunHistoryResponseDto](doc//RunHistoryResponseDto.md) + - [RunResponseDto](doc//RunResponseDto.md) + - [RunStatus](doc//RunStatus.md) + - [RunType](doc//RunType.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) @@ -549,6 +631,8 @@ Class | Method | HTTP request | Description - [SharedLinksUpdate](doc//SharedLinksUpdate.md) - [SignUpDto](doc//SignUpDto.md) - [SmartSearchDto](doc//SmartSearchDto.md) + - [SnapshotDto](doc//SnapshotDto.md) + - [SnapshotSummaryDto](doc//SnapshotSummaryDto.md) - [SourceType](doc//SourceType.md) - [StackCreateDto](doc//StackCreateDto.md) - [StackResponseDto](doc//StackResponseDto.md) @@ -633,6 +717,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 d5a6f483dc..215fe768ae 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'; @@ -68,6 +78,7 @@ part 'api/users_admin_api.dart'; part 'api/views_api.dart'; part 'api/workflows_api.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'; @@ -134,6 +145,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'; @@ -143,15 +158,20 @@ part 'model/cast_response.dart'; part 'model/cast_update.dart'; part 'model/change_password_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'; part 'model/database_backup_list_response_dto.dart'; +part 'model/device_flow_response_dto.dart'; part 'model/download_archive_dto.dart'; part 'model/download_archive_info.dart'; part 'model/download_info_dto.dart'; @@ -167,16 +187,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'; @@ -217,6 +249,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'; @@ -237,8 +270,6 @@ part 'model/pin_code_setup_dto.dart'; part 'model/places_response_dto.dart'; part 'model/plugin_method_response_dto.dart'; part 'model/plugin_response_dto.dart'; -part 'model/plugin_template_response_dto.dart'; -part 'model/plugin_template_step_response_dto.dart'; part 'model/purchase_response.dart'; part 'model/purchase_update.dart'; part 'model/queue_command.dart'; @@ -258,8 +289,35 @@ 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/retention_policy_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_response_dto.dart'; +part 'model/run_status.dart'; +part 'model/run_type.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'; @@ -294,6 +352,8 @@ 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/snapshot_summary_dto.dart'; part 'model/source_type.dart'; part 'model/stack_create_dto.dart'; part 'model/stack_response_dto.dart'; @@ -378,6 +438,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..e8f45989c9 --- /dev/null +++ b/mobile/openapi/lib/api/auth_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 AuthApi { + AuthApi([ApiClient? apiClient]) : apiClient = apiClient ?? defaultApiClient; + + final ApiClient apiClient; + + /// Performs an HTTP 'GET /yucca/auth/oidc/device' operation and returns the [Response]. + Future oidcDeviceFlowWithHttpInfo() async { + // ignore: prefer_const_declarations + final apiPath = r'/yucca/auth/oidc/device'; + + // 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 oidcDeviceFlow() async { + final response = await oidcDeviceFlowWithHttpInfo(); + 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), 'DeviceFlowResponseDto',) as DeviceFlowResponseDto; + + } + return null; + } +} 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..387c93a339 --- /dev/null +++ b/mobile/openapi/lib/api/repository_api.dart @@ -0,0 +1,789 @@ +// +// 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}' operation and returns the [Response]. + /// Parameters: + /// + /// * [String] id (required): + Future deleteRepositoryWithHttpInfo(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, + 'DELETE', + queryParams, + postBody, + headerParams, + formParams, + contentTypes.isEmpty ? null : contentTypes.first, + ); + } + + /// Parameters: + /// + /// * [String] id (required): + Future deleteRepository(String id,) async { + final response = await deleteRepositoryWithHttpInfo(id,); + if (response.statusCode >= HttpStatus.badRequest) { + throw ApiException(response.statusCode, await _decodeBodyBytes(response)); + } + } + + /// 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/prune' operation and returns the [Response]. + /// Parameters: + /// + /// * [String] id (required): + Future pruneRepositoryWithHttpInfo(String id,) async { + // ignore: prefer_const_declarations + final apiPath = r'/yucca/repository/{id}/snapshots/prune' + .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 pruneRepository(String id,) async { + final response = await pruneRepositoryWithHttpInfo(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/{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..5bdab9ec7d --- /dev/null +++ b/mobile/openapi/lib/api/run_history_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 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 getRunWithHttpInfo(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 getRun(String id,) async { + final response = await getRunWithHttpInfo(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), 'RunResponseDto',) as RunResponseDto; + + } + return null; + } + + /// Performs an HTTP 'GET /yucca/logs/{id}/stream' operation and returns the [Response]. + /// Parameters: + /// + /// * [String] id (required): + Future logStreamSseWithHttpInfo(String id,) async { + // ignore: prefer_const_declarations + final apiPath = r'/yucca/logs/{id}/stream' + .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..60bca1e280 --- /dev/null +++ b/mobile/openapi/lib/api/running_tasks_api.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 RunningTasksApi { + RunningTasksApi([ApiClient? apiClient]) : apiClient = apiClient ?? defaultApiClient; + + final ApiClient apiClient; + + /// Performs an HTTP 'POST /yucca/tasks/{parentId}/cancel' operation and returns the [Response]. + /// Parameters: + /// + /// * [String] parentId (required): + Future cancelTaskWithHttpInfo(String parentId,) async { + // ignore: prefer_const_declarations + final apiPath = r'/yucca/tasks/{parentId}/cancel' + .replaceAll('{parentId}', parentId); + + // 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] parentId (required): + Future cancelTask(String parentId,) async { + final response = await cancelTaskWithHttpInfo(parentId,); + if (response.statusCode >= HttpStatus.badRequest) { + throw ApiException(response.statusCode, await _decodeBodyBytes(response)); + } + } + + /// 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..37f8052ccb --- /dev/null +++ b/mobile/openapi/lib/api/schedule_api.dart @@ -0,0 +1,198 @@ +// +// 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 '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}' 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 3145b7faf4..dcd30994ba 100644 --- a/mobile/openapi/lib/api_client.dart +++ b/mobile/openapi/lib/api_client.dart @@ -13,7 +13,7 @@ part of openapi.api; class ApiClient { ApiClient({this.basePath = '/api', this.authentication,}); - String basePath; + final String basePath; final Authentication? authentication; var _client = Client(); @@ -44,9 +44,8 @@ class ApiClient { Object? body, Map headerParams, Map formParams, - String? contentType, { - Future? abortTrigger, - }) async { + String? contentType, + ) async { await authentication?.applyToParams(queryParams, headerParams); headerParams.addAll(_defaultHeaderMap); @@ -64,7 +63,7 @@ class ApiClient { body is MultipartFile && (contentType == null || !contentType.toLowerCase().startsWith('multipart/form-data')) ) { - final request = AbortableStreamedRequest(method, uri, abortTrigger: abortTrigger); + final request = StreamedRequest(method, uri); request.headers.addAll(headerParams); request.contentLength = body.length; body.finalize().listen( @@ -79,7 +78,7 @@ class ApiClient { } if (body is MultipartRequest) { - final request = AbortableMultipartRequest(method, uri, abortTrigger: abortTrigger); + final request = MultipartRequest(method, uri); request.fields.addAll(body.fields); request.files.addAll(body.files); request.headers.addAll(body.headers); @@ -93,19 +92,14 @@ class ApiClient { : await serializeAsync(body); final nullableHeaderParams = headerParams.isEmpty ? null : headerParams; - final request = AbortableRequest(method, uri, abortTrigger: abortTrigger); - if (nullableHeaderParams != null) { - request.headers.addAll(nullableHeaderParams); + switch(method) { + case 'POST': return await _client.post(uri, headers: nullableHeaderParams, body: msgBody,); + case 'PUT': return await _client.put(uri, headers: nullableHeaderParams, body: msgBody,); + case 'DELETE': return await _client.delete(uri, headers: nullableHeaderParams, body: msgBody,); + case 'PATCH': return await _client.patch(uri, headers: nullableHeaderParams, body: msgBody,); + case 'HEAD': return await _client.head(uri, headers: nullableHeaderParams,); + case 'GET': return await _client.get(uri, headers: nullableHeaderParams,); } - if (msgBody is String) { - request.body = msgBody; - } else if (msgBody is List) { - request.bodyBytes = msgBody; - } else if (msgBody is Map) { - request.bodyFields = msgBody; - } - final response = await _client.send(request); - return Response.fromStream(response); } on SocketException catch (error, trace) { throw ApiException.withInner( HttpStatus.badRequest, @@ -142,6 +136,11 @@ class ApiClient { trace, ); } + + throw ApiException( + HttpStatus.badRequest, + 'Invalid HTTP operation: $method $path', + ); } Future deserializeAsync(String value, String targetType, {bool growable = false,}) => @@ -183,6 +182,8 @@ class ApiClient { return valueString == 'true' || valueString == '1'; case 'DateTime': return value is DateTime ? value : DateTime.tryParse(value); + case 'ActiveScheduleItemDto': + return ActiveScheduleItemDto.fromJson(value); case 'ActivityCreateDto': return ActivityCreateDto.fromJson(value); case 'ActivityResponseDto': @@ -315,6 +316,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': @@ -333,16 +342,24 @@ class ApiClient { return ChangePasswordDto.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': @@ -351,6 +368,8 @@ class ApiClient { return DatabaseBackupDto.fromJson(value); case 'DatabaseBackupListResponseDto': return DatabaseBackupListResponseDto.fromJson(value); + case 'DeviceFlowResponseDto': + return DeviceFlowResponseDto.fromJson(value); case 'DownloadArchiveDto': return DownloadArchiveDto.fromJson(value); case 'DownloadArchiveInfo': @@ -381,12 +400,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': @@ -399,8 +436,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': @@ -481,6 +524,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': @@ -521,10 +566,6 @@ class ApiClient { return PluginMethodResponseDto.fromJson(value); case 'PluginResponseDto': return PluginResponseDto.fromJson(value); - case 'PluginTemplateResponseDto': - return PluginTemplateResponseDto.fromJson(value); - case 'PluginTemplateStepResponseDto': - return PluginTemplateStepResponseDto.fromJson(value); case 'PurchaseResponse': return PurchaseResponse.fromJson(value); case 'PurchaseUpdate': @@ -563,10 +604,64 @@ 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 'RetentionPolicyDto': + return RetentionPolicyDto.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 'RunResponseDto': + return RunResponseDto.fromJson(value); + case 'RunStatus': + return RunStatusTypeTransformer().decode(value); + case 'RunType': + return RunTypeTypeTransformer().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': @@ -635,6 +730,10 @@ class ApiClient { return SignUpDto.fromJson(value); case 'SmartSearchDto': return SmartSearchDto.fromJson(value); + case 'SnapshotDto': + return SnapshotDto.fromJson(value); + case 'SnapshotSummaryDto': + return SnapshotSummaryDto.fromJson(value); case 'SourceType': return SourceTypeTypeTransformer().decode(value); case 'StackCreateDto': @@ -803,6 +902,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 b5d348edd6..5e3ecae644 100644 --- a/mobile/openapi/lib/api_helper.dart +++ b/mobile/openapi/lib/api_helper.dart @@ -94,6 +94,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(); } @@ -157,6 +160,12 @@ 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 RunType) { + return RunTypeTypeTransformer().encode(value).toString(); + } if (value is SearchSuggestionType) { return SearchSuggestionTypeTypeTransformer().encode(value).toString(); } @@ -175,6 +184,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..13d83793a7 --- /dev/null +++ b/mobile/openapi/lib/model/configure_immich_integration_request_dto.dart @@ -0,0 +1,152 @@ +// +// 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, + this.retentionPolicy, + required this.worm, + }); + + bool backupConfiguration; + + String cron; + + List dataFolders; + + ConfigureImmichIntegrationRequestDtoLibraries libraries; + + String name; + + RetentionPolicyDto? retentionPolicy; + + 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.retentionPolicy == retentionPolicy && + other.worm == worm; + + @override + int get hashCode => + // ignore: unnecessary_parenthesis + (backupConfiguration.hashCode) + + (cron.hashCode) + + (dataFolders.hashCode) + + (libraries.hashCode) + + (name.hashCode) + + (retentionPolicy == null ? 0 : retentionPolicy!.hashCode) + + (worm.hashCode); + + @override + String toString() => 'ConfigureImmichIntegrationRequestDto[backupConfiguration=$backupConfiguration, cron=$cron, dataFolders=$dataFolders, libraries=$libraries, name=$name, retentionPolicy=$retentionPolicy, 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; + if (this.retentionPolicy != null) { + json[r'retentionPolicy'] = this.retentionPolicy; + } else { + // json[r'retentionPolicy'] = null; + } + 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')!, + retentionPolicy: RetentionPolicyDto.fromJson(json[r'retentionPolicy']), + 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/device_flow_response_dto.dart b/mobile/openapi/lib/model/device_flow_response_dto.dart new file mode 100644 index 0000000000..fa8cefa29f --- /dev/null +++ b/mobile/openapi/lib/model/device_flow_response_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 DeviceFlowResponseDto { + /// Returns a new [DeviceFlowResponseDto] instance. + DeviceFlowResponseDto({ + required this.userCode, + required this.verificationUri, + }); + + String userCode; + + String verificationUri; + + @override + bool operator ==(Object other) => identical(this, other) || other is DeviceFlowResponseDto && + other.userCode == userCode && + other.verificationUri == verificationUri; + + @override + int get hashCode => + // ignore: unnecessary_parenthesis + (userCode.hashCode) + + (verificationUri.hashCode); + + @override + String toString() => 'DeviceFlowResponseDto[userCode=$userCode, verificationUri=$verificationUri]'; + + Map toJson() { + final json = {}; + json[r'userCode'] = this.userCode; + json[r'verificationUri'] = this.verificationUri; + return json; + } + + /// Returns a new [DeviceFlowResponseDto] instance and imports its values from + /// [value] if it's a [Map], null otherwise. + // ignore: prefer_constructors_over_static_methods + static DeviceFlowResponseDto? fromJson(dynamic value) { + upgradeDto(value, "DeviceFlowResponseDto"); + if (value is Map) { + final json = value.cast(); + + return DeviceFlowResponseDto( + userCode: mapValueOfType(json, r'userCode')!, + verificationUri: mapValueOfType(json, r'verificationUri')!, + ); + } + 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 = DeviceFlowResponseDto.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 = DeviceFlowResponseDto.fromJson(entry.value); + if (value != null) { + map[entry.key] = value; + } + } + } + return map; + } + + // maps a json object with a list of DeviceFlowResponseDto-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] = DeviceFlowResponseDto.listFromJson(entry.value, growable: growable,); + } + } + return map; + } + + /// The list of required keys that must be present in a JSON. + static const requiredKeys = { + 'userCode', + 'verificationUri', + }; +} + 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..c8ad94f749 --- /dev/null +++ b/mobile/openapi/lib/model/repository_configuration_dto.dart @@ -0,0 +1,112 @@ +// +// 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 [], + this.retentionPolicy, + }); + + List paths; + + RetentionPolicyDto? retentionPolicy; + + @override + bool operator ==(Object other) => identical(this, other) || other is RepositoryConfigurationDto && + _deepEquality.equals(other.paths, paths) && + other.retentionPolicy == retentionPolicy; + + @override + int get hashCode => + // ignore: unnecessary_parenthesis + (paths.hashCode) + + (retentionPolicy == null ? 0 : retentionPolicy!.hashCode); + + @override + String toString() => 'RepositoryConfigurationDto[paths=$paths, retentionPolicy=$retentionPolicy]'; + + Map toJson() { + final json = {}; + json[r'paths'] = this.paths; + if (this.retentionPolicy != null) { + json[r'retentionPolicy'] = this.retentionPolicy; + } else { + // json[r'retentionPolicy'] = null; + } + 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 [], + retentionPolicy: RetentionPolicyDto.fromJson(json[r'retentionPolicy']), + ); + } + 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..c91ec2dfcc --- /dev/null +++ b/mobile/openapi/lib/model/repository_update_request_dto.dart @@ -0,0 +1,128 @@ +// +// 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 [], + this.retentionPolicy, + }); + + /// + /// 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; + + RetentionPolicyDto? retentionPolicy; + + @override + bool operator ==(Object other) => identical(this, other) || other is RepositoryUpdateRequestDto && + other.name == name && + _deepEquality.equals(other.paths, paths) && + other.retentionPolicy == retentionPolicy; + + @override + int get hashCode => + // ignore: unnecessary_parenthesis + (name == null ? 0 : name!.hashCode) + + (paths.hashCode) + + (retentionPolicy == null ? 0 : retentionPolicy!.hashCode); + + @override + String toString() => 'RepositoryUpdateRequestDto[name=$name, paths=$paths, retentionPolicy=$retentionPolicy]'; + + Map toJson() { + final json = {}; + if (this.name != null) { + json[r'name'] = this.name; + } else { + // json[r'name'] = null; + } + json[r'paths'] = this.paths; + if (this.retentionPolicy != null) { + json[r'retentionPolicy'] = this.retentionPolicy; + } else { + // json[r'retentionPolicy'] = null; + } + 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 [], + retentionPolicy: RetentionPolicyDto.fromJson(json[r'retentionPolicy']), + ); + } + 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/retention_policy_dto.dart b/mobile/openapi/lib/model/retention_policy_dto.dart new file mode 100644 index 0000000000..cc5deca9c9 --- /dev/null +++ b/mobile/openapi/lib/model/retention_policy_dto.dart @@ -0,0 +1,210 @@ +// +// 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 RetentionPolicyDto { + /// Returns a new [RetentionPolicyDto] instance. + RetentionPolicyDto({ + this.keepLast, + this.keepWithin, + this.keepWithinDaily, + this.keepWithinHourly, + this.keepWithinMonthly, + this.keepWithinWeekly, + this.keepWithinYearly, + }); + + /// + /// 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? keepLast; + + /// + /// 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? keepWithin; + + /// + /// 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? keepWithinDaily; + + /// + /// 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? keepWithinHourly; + + /// + /// 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? keepWithinMonthly; + + /// + /// 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? keepWithinWeekly; + + /// + /// 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? keepWithinYearly; + + @override + bool operator ==(Object other) => identical(this, other) || other is RetentionPolicyDto && + other.keepLast == keepLast && + other.keepWithin == keepWithin && + other.keepWithinDaily == keepWithinDaily && + other.keepWithinHourly == keepWithinHourly && + other.keepWithinMonthly == keepWithinMonthly && + other.keepWithinWeekly == keepWithinWeekly && + other.keepWithinYearly == keepWithinYearly; + + @override + int get hashCode => + // ignore: unnecessary_parenthesis + (keepLast == null ? 0 : keepLast!.hashCode) + + (keepWithin == null ? 0 : keepWithin!.hashCode) + + (keepWithinDaily == null ? 0 : keepWithinDaily!.hashCode) + + (keepWithinHourly == null ? 0 : keepWithinHourly!.hashCode) + + (keepWithinMonthly == null ? 0 : keepWithinMonthly!.hashCode) + + (keepWithinWeekly == null ? 0 : keepWithinWeekly!.hashCode) + + (keepWithinYearly == null ? 0 : keepWithinYearly!.hashCode); + + @override + String toString() => 'RetentionPolicyDto[keepLast=$keepLast, keepWithin=$keepWithin, keepWithinDaily=$keepWithinDaily, keepWithinHourly=$keepWithinHourly, keepWithinMonthly=$keepWithinMonthly, keepWithinWeekly=$keepWithinWeekly, keepWithinYearly=$keepWithinYearly]'; + + Map toJson() { + final json = {}; + if (this.keepLast != null) { + json[r'keepLast'] = this.keepLast; + } else { + // json[r'keepLast'] = null; + } + if (this.keepWithin != null) { + json[r'keepWithin'] = this.keepWithin; + } else { + // json[r'keepWithin'] = null; + } + if (this.keepWithinDaily != null) { + json[r'keepWithinDaily'] = this.keepWithinDaily; + } else { + // json[r'keepWithinDaily'] = null; + } + if (this.keepWithinHourly != null) { + json[r'keepWithinHourly'] = this.keepWithinHourly; + } else { + // json[r'keepWithinHourly'] = null; + } + if (this.keepWithinMonthly != null) { + json[r'keepWithinMonthly'] = this.keepWithinMonthly; + } else { + // json[r'keepWithinMonthly'] = null; + } + if (this.keepWithinWeekly != null) { + json[r'keepWithinWeekly'] = this.keepWithinWeekly; + } else { + // json[r'keepWithinWeekly'] = null; + } + if (this.keepWithinYearly != null) { + json[r'keepWithinYearly'] = this.keepWithinYearly; + } else { + // json[r'keepWithinYearly'] = null; + } + return json; + } + + /// Returns a new [RetentionPolicyDto] instance and imports its values from + /// [value] if it's a [Map], null otherwise. + // ignore: prefer_constructors_over_static_methods + static RetentionPolicyDto? fromJson(dynamic value) { + upgradeDto(value, "RetentionPolicyDto"); + if (value is Map) { + final json = value.cast(); + + return RetentionPolicyDto( + keepLast: num.parse('${json[r'keepLast']}'), + keepWithin: mapValueOfType(json, r'keepWithin'), + keepWithinDaily: mapValueOfType(json, r'keepWithinDaily'), + keepWithinHourly: mapValueOfType(json, r'keepWithinHourly'), + keepWithinMonthly: mapValueOfType(json, r'keepWithinMonthly'), + keepWithinWeekly: mapValueOfType(json, r'keepWithinWeekly'), + keepWithinYearly: mapValueOfType(json, r'keepWithinYearly'), + ); + } + 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 = RetentionPolicyDto.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 = RetentionPolicyDto.fromJson(entry.value); + if (value != null) { + map[entry.key] = value; + } + } + } + return map; + } + + // maps a json object with a list of RetentionPolicyDto-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] = RetentionPolicyDto.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/run_dto.dart b/mobile/openapi/lib/model/run_dto.dart new file mode 100644 index 0000000000..b0a221d261 --- /dev/null +++ b/mobile/openapi/lib/model/run_dto.dart @@ -0,0 +1,147 @@ +// +// 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.repositoryId, + required this.start, + required this.status, + required this.type, + }); + + String end; + + String id; + + String logFilePath; + + String repositoryId; + + String start; + + RunStatus status; + + RunType type; + + @override + bool operator ==(Object other) => identical(this, other) || other is RunDto && + other.end == end && + other.id == id && + other.logFilePath == logFilePath && + other.repositoryId == repositoryId && + other.start == start && + other.status == status && + other.type == type; + + @override + int get hashCode => + // ignore: unnecessary_parenthesis + (end.hashCode) + + (id.hashCode) + + (logFilePath.hashCode) + + (repositoryId.hashCode) + + (start.hashCode) + + (status.hashCode) + + (type.hashCode); + + @override + String toString() => 'RunDto[end=$end, id=$id, logFilePath=$logFilePath, repositoryId=$repositoryId, start=$start, status=$status, type=$type]'; + + Map toJson() { + final json = {}; + json[r'end'] = this.end; + json[r'id'] = this.id; + json[r'logFilePath'] = this.logFilePath; + json[r'repositoryId'] = this.repositoryId; + json[r'start'] = this.start; + json[r'status'] = this.status; + json[r'type'] = this.type; + 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')!, + repositoryId: mapValueOfType(json, r'repositoryId')!, + start: mapValueOfType(json, r'start')!, + status: RunStatus.fromJson(json[r'status'])!, + type: RunType.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 = 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', + 'repositoryId', + 'start', + 'status', + 'type', + }; +} + 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_response_dto.dart b/mobile/openapi/lib/model/run_response_dto.dart new file mode 100644 index 0000000000..ef17249baf --- /dev/null +++ b/mobile/openapi/lib/model/run_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 RunResponseDto { + /// Returns a new [RunResponseDto] instance. + RunResponseDto({ + required this.run, + }); + + RunDto run; + + @override + bool operator ==(Object other) => identical(this, other) || other is RunResponseDto && + other.run == run; + + @override + int get hashCode => + // ignore: unnecessary_parenthesis + (run.hashCode); + + @override + String toString() => 'RunResponseDto[run=$run]'; + + Map toJson() { + final json = {}; + json[r'run'] = this.run; + return json; + } + + /// Returns a new [RunResponseDto] instance and imports its values from + /// [value] if it's a [Map], null otherwise. + // ignore: prefer_constructors_over_static_methods + static RunResponseDto? fromJson(dynamic value) { + upgradeDto(value, "RunResponseDto"); + if (value is Map) { + final json = value.cast(); + + return RunResponseDto( + run: RunDto.fromJson(json[r'run'])!, + ); + } + 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 = RunResponseDto.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 = RunResponseDto.fromJson(entry.value); + if (value != null) { + map[entry.key] = value; + } + } + } + return map; + } + + // maps a json object with a list of RunResponseDto-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] = RunResponseDto.listFromJson(entry.value, growable: growable,); + } + } + return map; + } + + /// The list of required keys that must be present in a JSON. + static const requiredKeys = { + 'run', + }; +} + 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/run_type.dart b/mobile/openapi/lib/model/run_type.dart new file mode 100644 index 0000000000..b8eb404bb0 --- /dev/null +++ b/mobile/openapi/lib/model/run_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 RunType { + /// Instantiate a new enum with the provided [value]. + const RunType._(this.value); + + /// The underlying value of this enum member. + final String value; + + @override + String toString() => value; + + String toJson() => value; + + static const schedule = RunType._(r'schedule'); + static const restore = RunType._(r'restore'); + static const backup = RunType._(r'backup'); + static const forget = RunType._(r'forget'); + + /// List of all possible values in this [enum][RunType]. + static const values = [ + schedule, + restore, + backup, + forget, + ]; + + static RunType? fromJson(dynamic value) => RunTypeTypeTransformer().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 = RunType.fromJson(row); + if (value != null) { + result.add(value); + } + } + } + return result.toList(growable: growable); + } +} + +/// Transformation class that can [encode] an instance of [RunType] to String, +/// and [decode] dynamic data back to [RunType]. +class RunTypeTypeTransformer { + factory RunTypeTypeTransformer() => _instance ??= const RunTypeTypeTransformer._(); + + const RunTypeTypeTransformer._(); + + String encode(RunType data) => data.value; + + /// Decodes a [dynamic value][data] to a RunType. + /// + /// 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. + RunType? decode(dynamic data, {bool allowNull = true}) { + if (data != null) { + switch (data) { + case r'schedule': return RunType.schedule; + case r'restore': return RunType.restore; + case r'backup': return RunType.backup; + case r'forget': return RunType.forget; + default: + if (!allowNull) { + throw ArgumentError('Unknown enum value to decode: $data'); + } + } + } + return null; + } + + /// Singleton [RunTypeTypeTransformer] instance. + static RunTypeTypeTransformer? _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..074b30173b --- /dev/null +++ b/mobile/openapi/lib/model/snapshot_dto.dart @@ -0,0 +1,134 @@ +// +// 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 [], + this.summary, + required this.time, + }); + + String id; + + List paths; + + /// + /// 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. + /// + SnapshotSummaryDto? summary; + + String time; + + @override + bool operator ==(Object other) => identical(this, other) || other is SnapshotDto && + other.id == id && + _deepEquality.equals(other.paths, paths) && + other.summary == summary && + other.time == time; + + @override + int get hashCode => + // ignore: unnecessary_parenthesis + (id.hashCode) + + (paths.hashCode) + + (summary == null ? 0 : summary!.hashCode) + + (time.hashCode); + + @override + String toString() => 'SnapshotDto[id=$id, paths=$paths, summary=$summary, time=$time]'; + + Map toJson() { + final json = {}; + json[r'id'] = this.id; + json[r'paths'] = this.paths; + if (this.summary != null) { + json[r'summary'] = this.summary; + } else { + // json[r'summary'] = null; + } + 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 [], + summary: SnapshotSummaryDto.fromJson(json[r'summary']), + 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/snapshot_summary_dto.dart b/mobile/openapi/lib/model/snapshot_summary_dto.dart new file mode 100644 index 0000000000..1c69d7c3f5 --- /dev/null +++ b/mobile/openapi/lib/model/snapshot_summary_dto.dart @@ -0,0 +1,139 @@ +// +// 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 SnapshotSummaryDto { + /// Returns a new [SnapshotSummaryDto] instance. + SnapshotSummaryDto({ + required this.dataAdded, + required this.filesChanged, + required this.filesNew, + required this.filesUnmodified, + required this.totalBytes, + required this.totalFiles, + }); + + num dataAdded; + + num filesChanged; + + num filesNew; + + num filesUnmodified; + + num totalBytes; + + num totalFiles; + + @override + bool operator ==(Object other) => identical(this, other) || other is SnapshotSummaryDto && + other.dataAdded == dataAdded && + other.filesChanged == filesChanged && + other.filesNew == filesNew && + other.filesUnmodified == filesUnmodified && + other.totalBytes == totalBytes && + other.totalFiles == totalFiles; + + @override + int get hashCode => + // ignore: unnecessary_parenthesis + (dataAdded.hashCode) + + (filesChanged.hashCode) + + (filesNew.hashCode) + + (filesUnmodified.hashCode) + + (totalBytes.hashCode) + + (totalFiles.hashCode); + + @override + String toString() => 'SnapshotSummaryDto[dataAdded=$dataAdded, filesChanged=$filesChanged, filesNew=$filesNew, filesUnmodified=$filesUnmodified, totalBytes=$totalBytes, totalFiles=$totalFiles]'; + + Map toJson() { + final json = {}; + json[r'dataAdded'] = this.dataAdded; + json[r'filesChanged'] = this.filesChanged; + json[r'filesNew'] = this.filesNew; + json[r'filesUnmodified'] = this.filesUnmodified; + json[r'totalBytes'] = this.totalBytes; + json[r'totalFiles'] = this.totalFiles; + return json; + } + + /// Returns a new [SnapshotSummaryDto] instance and imports its values from + /// [value] if it's a [Map], null otherwise. + // ignore: prefer_constructors_over_static_methods + static SnapshotSummaryDto? fromJson(dynamic value) { + upgradeDto(value, "SnapshotSummaryDto"); + if (value is Map) { + final json = value.cast(); + + return SnapshotSummaryDto( + dataAdded: num.parse('${json[r'dataAdded']}'), + filesChanged: num.parse('${json[r'filesChanged']}'), + filesNew: num.parse('${json[r'filesNew']}'), + filesUnmodified: num.parse('${json[r'filesUnmodified']}'), + totalBytes: num.parse('${json[r'totalBytes']}'), + totalFiles: num.parse('${json[r'totalFiles']}'), + ); + } + 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 = SnapshotSummaryDto.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 = SnapshotSummaryDto.fromJson(entry.value); + if (value != null) { + map[entry.key] = value; + } + } + } + return map; + } + + // maps a json object with a list of SnapshotSummaryDto-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] = SnapshotSummaryDto.listFromJson(entry.value, growable: growable,); + } + } + return map; + } + + /// The list of required keys that must be present in a JSON. + static const requiredKeys = { + 'dataAdded', + 'filesChanged', + 'filesNew', + 'filesUnmodified', + 'totalBytes', + 'totalFiles', + }; +} + 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 5e9b460ada..94dfec933b 100644 --- a/open-api/immich-openapi-specs.json +++ b/open-api/immich-openapi-specs.json @@ -15271,6 +15271,993 @@ ], "x-immich-permission": "workflow.read" } + }, + "/yucca/auth/oidc/device": { + "get": { + "operationId": "oidcDeviceFlow", + "parameters": [], + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/DeviceFlowResponseDto" + } + } + }, + "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": "getRun", + "parameters": [ + { + "name": "id", + "required": true, + "in": "path", + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/RunResponseDto" + } + } + }, + "description": "" + } + }, + "tags": [ + "RunHistory" + ] + } + }, + "/yucca/logs/{id}/stream": { + "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}": { + "delete": { + "operationId": "deleteRepository", + "parameters": [ + { + "name": "id", + "required": true, + "in": "path", + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "" + } + }, + "tags": [ + "Repository" + ] + }, + "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/prune": { + "post": { + "operationId": "pruneRepository", + "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}/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/tasks": { + "get": { + "operationId": "getRunningTasks", + "parameters": [], + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/RunningTaskListResponse" + } + } + }, + "description": "" + } + }, + "tags": [ + "RunningTasks" + ] + } + }, + "/yucca/tasks/{parentId}/cancel": { + "post": { + "operationId": "cancelTask", + "parameters": [ + { + "name": "parentId", + "required": true, + "in": "path", + "schema": { + "type": "string" + } + } + ], + "responses": { + "201": { + "description": "" + } + }, + "tags": [ + "RunningTasks" + ] + } } }, "info": { @@ -15454,6 +16441,25 @@ } }, "schemas": { + "ActiveScheduleItemDto": { + "properties": { + "repositoryId": { + "type": "string" + }, + "status": { + "allOf": [ + { + "$ref": "#/components/schemas/TaskStatus" + } + ] + } + }, + "required": [ + "repositoryId", + "status" + ], + "type": "object" + }, "ActivityCreateDto": { "description": "Activity create", "properties": { @@ -17213,6 +18219,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": [ @@ -17344,6 +18409,62 @@ ], "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" + }, + "retentionPolicy": { + "allOf": [ + { + "$ref": "#/components/schemas/RetentionPolicyDto" + } + ], + "nullable": true, + "type": "object" + }, + "worm": { + "type": "boolean" + } + }, + "required": [ + "backupConfiguration", + "cron", + "dataFolders", + "libraries", + "name", + "worm" + ], + "type": "object" + }, "ContributorCountResponseDto": { "properties": { "assetCount": { @@ -17430,6 +18551,17 @@ ], "type": "object" }, + "CreateLocalBackendRequestDto": { + "properties": { + "path": { + "type": "string" + } + }, + "required": [ + "path" + ], + "type": "object" + }, "CreateProfileImageDto": { "properties": { "file": { @@ -17503,6 +18635,17 @@ ], "type": "object" }, + "CurrentRecoveryKeyResponse": { + "properties": { + "recoveryKey": { + "type": "string" + } + }, + "required": [ + "recoveryKey" + ], + "type": "object" + }, "DatabaseBackupConfig": { "properties": { "cronExpression": { @@ -17592,6 +18735,21 @@ }, "type": "object" }, + "DeviceFlowResponseDto": { + "properties": { + "userCode": { + "type": "string" + }, + "verificationUri": { + "type": "string" + } + }, + "required": [ + "userCode", + "verificationUri" + ], + "type": "object" + }, "DownloadArchiveDto": { "properties": { "assetIds": { @@ -18065,6 +19223,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": { @@ -18103,6 +19298,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": { @@ -18315,6 +19676,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": [ @@ -18327,6 +19731,17 @@ ], "type": "string" }, + "LogResponseDto": { + "properties": { + "logId": { + "type": "string" + } + }, + "required": [ + "logId" + ], + "type": "object" + }, "LoginCredentialDto": { "properties": { "email": { @@ -19475,6 +20890,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": { @@ -20828,6 +22270,249 @@ ], "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" + }, + "retentionPolicy": { + "allOf": [ + { + "$ref": "#/components/schemas/RetentionPolicyDto" + } + ], + "nullable": true, + "type": "object" + } + }, + "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" + }, + "retentionPolicy": { + "allOf": [ + { + "$ref": "#/components/schemas/RetentionPolicyDto" + } + ], + "nullable": true, + "type": "object" + } + }, + "type": "object" + }, + "RepositoryUpdateResponseDto": { + "properties": { + "repository": { + "$ref": "#/components/schemas/LocalRepositoryDto" + } + }, + "required": [ + "repository" + ], + "type": "object" + }, + "RetentionPolicyDto": { + "properties": { + "keepLast": { + "type": "number" + }, + "keepWithin": { + "type": "string" + }, + "keepWithinDaily": { + "type": "string" + }, + "keepWithinHourly": { + "type": "string" + }, + "keepWithinMonthly": { + "type": "string" + }, + "keepWithinWeekly": { + "type": "string" + }, + "keepWithinYearly": { + "type": "string" + } + }, + "type": "object" + }, "ReverseGeocodingStateResponseDto": { "properties": { "lastImportFileName": { @@ -20859,6 +22544,247 @@ ], "type": "object" }, + "RunDto": { + "properties": { + "end": { + "type": "string" + }, + "id": { + "type": "string" + }, + "logFilePath": { + "type": "string" + }, + "repositoryId": { + "type": "string" + }, + "start": { + "type": "string" + }, + "status": { + "allOf": [ + { + "$ref": "#/components/schemas/RunStatus" + } + ] + }, + "type": { + "allOf": [ + { + "$ref": "#/components/schemas/RunType" + } + ] + } + }, + "required": [ + "end", + "id", + "logFilePath", + "repositoryId", + "start", + "status", + "type" + ], + "type": "object" + }, + "RunHistoryResponseDto": { + "properties": { + "runs": { + "items": { + "$ref": "#/components/schemas/RunDto" + }, + "type": "array" + } + }, + "required": [ + "runs" + ], + "type": "object" + }, + "RunResponseDto": { + "properties": { + "run": { + "$ref": "#/components/schemas/RunDto" + } + }, + "required": [ + "run" + ], + "type": "object" + }, + "RunStatus": { + "enum": [ + "incomplete", + "complete", + "failed" + ], + "type": "string" + }, + "RunType": { + "enum": [ + "schedule", + "restore", + "backup", + "forget" + ], + "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": { @@ -22174,6 +24100,62 @@ }, "type": "object" }, + "SnapshotDto": { + "properties": { + "id": { + "type": "string" + }, + "paths": { + "items": { + "type": "string" + }, + "type": "array" + }, + "summary": { + "$ref": "#/components/schemas/SnapshotSummaryDto" + }, + "time": { + "type": "string" + } + }, + "required": [ + "id", + "paths", + "time" + ], + "type": "object" + }, + "SnapshotSummaryDto": { + "properties": { + "dataAdded": { + "type": "number" + }, + "filesChanged": { + "type": "number" + }, + "filesNew": { + "type": "number" + }, + "filesUnmodified": { + "type": "number" + }, + "totalBytes": { + "type": "number" + }, + "totalFiles": { + "type": "number" + } + }, + "required": [ + "dataAdded", + "filesChanged", + "filesNew", + "filesUnmodified", + "totalBytes", + "totalFiles" + ], + "type": "object" + }, "SourceType": { "description": "Face detection source type", "enum": [ @@ -25158,6 +27140,23 @@ }, "type": "object" }, + "TaskStatus": { + "enum": [ + "incomplete", + "complete", + "failed" + ], + "type": "string" + }, + "TaskType": { + "enum": [ + "schedule", + "restore", + "backup", + "forget" + ], + "type": "string" + }, "TemplateDto": { "properties": { "template": { diff --git a/packages/sdk/src/fetch-client.ts b/packages/sdk/src/fetch-client.ts index e9388eb9de..66a25a04f3 100644 --- a/packages/sdk/src/fetch-client.ts +++ b/packages/sdk/src/fetch-client.ts @@ -2767,6 +2767,236 @@ export type WorkflowShareResponseDto = { /** Workflow trigger type */ trigger: WorkflowTrigger; }; +export type DeviceFlowResponseDto = { + userCode: string; + verificationUri: string; +}; +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 RetentionPolicyDto = { + keepLast?: number; + keepWithin?: string; + keepWithinDaily?: string; + keepWithinHourly?: string; + keepWithinMonthly?: string; + keepWithinWeekly?: string; + keepWithinYearly?: string; +}; +export type ConfigureImmichIntegrationRequestDto = { + backupConfiguration: boolean; + cron: string; + dataFolders: string[]; + libraries: "all" | string[]; + name: string; + retentionPolicy?: (RetentionPolicyDto) | null; + worm: boolean; +}; +export type RunDto = { + end: string; + id: string; + logFilePath: string; + repositoryId: string; + start: string; + status: RunStatus; + "type": RunType; +}; +export type RunResponseDto = { + run: RunDto; +}; +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[]; + retentionPolicy?: (RetentionPolicyDto) | null; +}; +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 SnapshotSummaryDto = { + dataAdded: number; + filesChanged: number; + filesNew: number; + filesUnmodified: number; + totalBytes: number; + totalFiles: number; +}; +export type SnapshotDto = { + id: string; + paths: string[]; + summary?: SnapshotSummaryDto; + 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[]; + retentionPolicy?: (RetentionPolicyDto) | null; +}; +export type RepositoryUpdateResponseDto = { + repository: LocalRepositoryDto; +}; +export type LogResponseDto = { + logId: string; +}; +export type RepositoryCheckImportResponseDto = { + readable: boolean; +}; +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 = { @@ -6752,6 +6982,361 @@ export function getWorkflowForShare({ id }: { ...opts })); } +export function oidcDeviceFlow(opts?: Oazapfts.RequestOpts) { + return oazapfts.ok(oazapfts.fetchJson<{ + status: 200; + data: DeviceFlowResponseDto; + }>("/yucca/auth/oidc/device", { + ...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 getRun({ id }: { + id: string; +}, opts?: Oazapfts.RequestOpts) { + return oazapfts.ok(oazapfts.fetchJson<{ + status: 200; + data: RunResponseDto; + }>(`/yucca/logs/${encodeURIComponent(id)}`, { + ...opts + })); +} +export function logStreamSse({ id }: { + id: string; +}, opts?: Oazapfts.RequestOpts) { + return oazapfts.ok(oazapfts.fetchText(`/yucca/logs/${encodeURIComponent(id)}/stream`, { + ...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 deleteRepository({ id }: { + id: string; +}, opts?: Oazapfts.RequestOpts) { + return oazapfts.ok(oazapfts.fetchText(`/yucca/repository/${encodeURIComponent(id)}`, { + ...opts, + method: "DELETE" + })); +} +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 pruneRepository({ id }: { + id: string; +}, opts?: Oazapfts.RequestOpts) { + return oazapfts.ok(oazapfts.fetchJson<{ + status: 200; + data: LogResponseDto; + }>(`/yucca/repository/${encodeURIComponent(id)}/snapshots/prune`, { + ...opts, + method: "POST" + })); +} +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 getRunningTasks(opts?: Oazapfts.RequestOpts) { + return oazapfts.ok(oazapfts.fetchJson<{ + status: 200; + data: RunningTaskListResponse; + }>("/yucca/tasks", { + ...opts + })); +} +export function cancelTask({ parentId }: { + parentId: string; +}, opts?: Oazapfts.RequestOpts) { + return oazapfts.ok(oazapfts.fetchText(`/yucca/tasks/${encodeURIComponent(parentId)}/cancel`, { + ...opts, + method: "POST" + })); +} export enum ReactionLevel { Album = "album", Asset = "asset" @@ -7320,6 +7905,33 @@ export enum AssetOrderBy { TakenAt = "takenAt", CreatedAt = "createdAt" } +export enum BackendType { + Yucca = "yucca", + Local = "local", + S3 = "s3" +} +export enum RunStatus { + Incomplete = "incomplete", + Complete = "complete", + Failed = "failed" +} +export enum RunType { + Schedule = "schedule", + Restore = "restore", + Backup = "backup", + Forget = "forget" +} +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 1a76031206..2131f5d759 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -109,6 +109,9 @@ importers: '@faker-js/faker': specifier: ^10.1.0 version: 10.4.0 + '@futo-org/backups-orchestrator-ui': + specifier: 0.1.72 + version: 0.1.72(@sveltejs/kit@2.60.1(@opentelemetry/api@1.9.1)(@sveltejs/vite-plugin-svelte@7.1.2(svelte@5.55.8(@typescript-eslint/types@8.59.4))(vite@8.0.13(@types/node@24.12.4)(esbuild@0.28.0)(jiti@2.7.0)(sass@1.99.0)(terser@5.47.1)(tsx@4.22.3)(yaml@2.9.0)))(svelte@5.55.8(@typescript-eslint/types@8.59.4))(typescript@6.0.3)(vite@8.0.13(@types/node@24.12.4)(esbuild@0.28.0)(jiti@2.7.0)(sass@1.99.0)(terser@5.47.1)(tsx@4.22.3)(yaml@2.9.0)))(svelte@5.55.8(@typescript-eslint/types@8.59.4)) '@immich/cli': specifier: workspace:* version: link:../packages/cli @@ -156,7 +159,7 @@ importers: version: 64.0.0(eslint@10.4.0(jiti@2.7.0)) exiftool-vendored: specifier: ^35.0.0 - version: 35.20.0 + version: 35.19.0 globals: specifier: ^17.0.0 version: 17.6.0 @@ -369,6 +372,9 @@ importers: '@extism/extism': specifier: 2.0.0-rc13 version: 2.0.0-rc13 + '@futo-org/backups-orchestrator-api': + specifier: 0.1.72 + version: 0.1.72(@nestjs/common@11.1.21(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.21)(@nestjs/platform-socket.io@11.1.21)(@nestjs/schedule@6.1.3(@nestjs/common@11.1.21(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.21))(@nestjs/websockets@11.1.21)(reflect-metadata@0.2.2) '@immich/plugin-sdk': specifier: workspace:* version: link:../packages/plugin-sdk @@ -377,34 +383,34 @@ importers: version: 0.5.2 '@nestjs/bullmq': specifier: ^11.0.1 - version: 11.0.4(@nestjs/common@11.1.21(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.21)(bullmq@5.76.10) + version: 11.0.4(@nestjs/common@11.1.21(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.21)(bullmq@5.76.10) '@nestjs/common': specifier: ^11.0.4 - version: 11.1.21(reflect-metadata@0.2.2)(rxjs@7.8.2) + version: 11.1.21(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.21(@nestjs/common@11.1.21(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/platform-express@11.1.21)(@nestjs/websockets@11.1.21)(reflect-metadata@0.2.2)(rxjs@7.8.2) + version: 11.1.21(@nestjs/common@11.1.21(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/platform-express@11.1.21)(@nestjs/websockets@11.1.21)(reflect-metadata@0.2.2)(rxjs@7.8.2) '@nestjs/platform-express': specifier: ^11.0.4 - version: 11.1.21(@nestjs/common@11.1.21(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.21) + version: 11.1.21(@nestjs/common@11.1.21(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.21) '@nestjs/platform-socket.io': specifier: ^11.0.4 - version: 11.1.21(@nestjs/common@11.1.21(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/websockets@11.1.21)(rxjs@7.8.2) + version: 11.1.21(@nestjs/common@11.1.21(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/websockets@11.1.21)(rxjs@7.8.2) '@nestjs/schedule': specifier: ^6.0.0 - version: 6.1.3(@nestjs/common@11.1.21(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.21) + version: 6.1.3(@nestjs/common@11.1.21(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.21) '@nestjs/swagger': specifier: ^11.4.2 - version: 11.4.3(@nestjs/common@11.1.21(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.21)(reflect-metadata@0.2.2)(typescript@6.0.3) + version: 11.4.3(@nestjs/common@11.1.21(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.21)(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2)(typescript@6.0.3) '@nestjs/websockets': specifier: ^11.0.4 - version: 11.1.21(@nestjs/common@11.1.21(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.21)(@nestjs/platform-socket.io@11.1.21)(reflect-metadata@0.2.2)(rxjs@7.8.2) + version: 11.1.21(@nestjs/common@11.1.21(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.21)(@nestjs/platform-socket.io@11.1.21)(reflect-metadata@0.2.2)(rxjs@7.8.2) '@opentelemetry/api': specifier: ^1.9.0 version: 1.9.1 '@opentelemetry/context-async-hooks': specifier: ^2.0.0 - version: 2.7.1(@opentelemetry/api@1.9.1) + version: 2.7.0(@opentelemetry/api@1.9.1) '@opentelemetry/exporter-prometheus': specifier: ^0.218.0 version: 0.218.0(@opentelemetry/api@1.9.1) @@ -422,10 +428,10 @@ importers: version: 0.70.0(@opentelemetry/api@1.9.1) '@opentelemetry/resources': specifier: ^2.0.1 - version: 2.7.1(@opentelemetry/api@1.9.1) + version: 2.7.0(@opentelemetry/api@1.9.1) '@opentelemetry/sdk-metrics': specifier: ^2.0.1 - version: 2.7.1(@opentelemetry/api@1.9.1) + version: 2.7.0(@opentelemetry/api@1.9.1) '@opentelemetry/sdk-node': specifier: ^0.218.0 version: 0.218.0(@opentelemetry/api@1.9.1) @@ -530,19 +536,19 @@ importers: version: 2.1.1 nest-commander: specifier: ^3.16.0 - version: 3.20.1(@nestjs/common@11.1.21(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.21)(@types/inquirer@8.2.12)(@types/node@24.12.4)(typescript@6.0.3) + version: 3.20.1(@nestjs/common@11.1.21(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.21)(@types/inquirer@8.2.12)(@types/node@24.12.4)(typescript@6.0.3) nestjs-cls: specifier: ^6.0.0 - version: 6.2.0(@nestjs/common@11.1.21(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.21)(reflect-metadata@0.2.2)(rxjs@7.8.2) + version: 6.2.0(@nestjs/common@11.1.21(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.21)(reflect-metadata@0.2.2)(rxjs@7.8.2) nestjs-kysely: specifier: 3.1.2 - version: 3.1.2(@nestjs/common@11.1.21(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.21)(kysely@0.28.17)(reflect-metadata@0.2.2) + version: 3.1.2(@nestjs/common@11.1.21(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.21)(kysely@0.28.17)(reflect-metadata@0.2.2) nestjs-otel: specifier: ^8.0.0 - version: 8.0.3(@nestjs/common@11.1.21(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.21) + version: 8.0.3(@nestjs/common@11.1.21(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.21) nestjs-zod: specifier: ^5.3.0 - version: 5.4.0(@nestjs/common@11.1.21(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/swagger@11.4.3(@nestjs/common@11.1.21(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.21)(reflect-metadata@0.2.2)(typescript@6.0.3))(rxjs@7.8.2)(zod@4.3.6) + version: 5.4.0(@nestjs/common@11.1.21(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/swagger@11.4.3(@nestjs/common@11.1.21(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.21)(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2)(typescript@6.0.3))(rxjs@7.8.2)(zod@4.3.6) nodemailer: specifier: ^8.0.0 version: 8.0.7 @@ -621,7 +627,7 @@ importers: version: 11.1.0(chokidar@4.0.3)(prettier@3.8.3)(typescript@6.0.3) '@nestjs/testing': specifier: ^11.0.4 - version: 11.1.21(@nestjs/common@11.1.21(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.21)(@nestjs/platform-express@11.1.21) + version: 11.1.21(@nestjs/common@11.1.21(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.21)(@nestjs/platform-express@11.1.21) '@swc/core': specifier: ^1.4.14 version: 1.15.33(@swc/helpers@0.5.22) @@ -757,6 +763,9 @@ importers: '@formatjs/icu-messageformat-parser': specifier: ^3.0.0 version: 3.5.9 + '@futo-org/backups-orchestrator-ui': + specifier: 0.1.72 + version: 0.1.72(@sveltejs/kit@2.60.1(@opentelemetry/api@1.9.1)(@sveltejs/vite-plugin-svelte@7.1.2(svelte@5.55.8(@typescript-eslint/types@8.59.4))(vite@8.0.13(@types/node@24.12.4)(esbuild@0.28.0)(jiti@2.7.0)(sass@1.99.0)(terser@5.47.1)(tsx@4.22.3)(yaml@2.9.0)))(svelte@5.55.8(@typescript-eslint/types@8.59.4))(typescript@6.0.3)(vite@8.0.13(@types/node@24.12.4)(esbuild@0.28.0)(jiti@2.7.0)(sass@1.99.0)(terser@5.47.1)(tsx@4.22.3)(yaml@2.9.0)))(svelte@5.55.8(@typescript-eslint/types@8.59.4)) '@immich/justified-layout-wasm': specifier: ^0.4.3 version: 0.4.3 @@ -3002,6 +3011,27 @@ packages: resolution: {integrity: sha512-YTVITFGN0/24PxzXrwqCgnyd7njDuzp5ZvaCx5nq/jg55kUYd94Nj8UTchBdBofi/L0nwRfjGOg0E41d2u9T1w==} engines: {node: '>=6'} + '@futo-org/backups-api-client@0.1.72': + resolution: {integrity: sha512-qWCGJzivSNcfFMGFRIfaxkSkoVdC6oBIcGyWma1hRpoaQyYM3vGfntzpsI9VbYp1tunoolzF/rSYvkwy3x/SXg==} + + '@futo-org/backups-orchestrator-api@0.1.72': + resolution: {integrity: sha512-SxxbA8GkovEw8TAuV8DHYBV+KA269OH1dgnNSK5t/1siQRV3bpRbbgd/13WN0VCsC8os8hvhp0xwi9sNXtiayA==} + peerDependencies: + '@nestjs/common': ^11.0.0 + '@nestjs/core': ^11.0.0 + '@nestjs/platform-socket.io': ^11.0.0 + '@nestjs/schedule': ^6.0.0 + '@nestjs/websockets': ^11.0.0 + + '@futo-org/backups-orchestrator-ui@0.1.72': + resolution: {integrity: sha512-aWswjn74Wmmleqb6HccXW+AFnv5EdjiBtwjPTCrQOccjL+AizrPVidgPBhCpTGoZr4LQDbqkmyd3lmvzkIdf1w==} + peerDependencies: + svelte: ^5.0.0 + + '@futo-org/restic-wrapper@1.2.1': + resolution: {integrity: sha512-shMx5f0/RTTYTvJ9Zryq7InWcmHm01kpIXy6wli/RIOx1Jjcx2j/Ab32WWhpYRTMxGhrKlOEmmen0qinMHFSNg==} + engines: {node: '>=20'} + '@golevelup/nestjs-discovery@5.0.0': resolution: {integrity: sha512-NaIWLCLI+XvneUK05LH2idHLmLNITYT88YnpOuUQmllKtiJNIS3woSt7QXrMZ5k3qUWuZpehEVz1JtlX4I1KyA==} peerDependencies: @@ -3214,6 +3244,16 @@ packages: resolution: {integrity: sha512-O1SJ+BbeFVsUTF4af1MfagJZM+lPgLjI8lQ3SZNjpo8SGJReSbUl2ii03OKuGni/G0yp2GnRLpOTNSHYGtVrcg==} hasBin: true + '@immich/svelte-markdown-preprocess@0.1.0': + resolution: {integrity: sha512-jgSOJEGLPKEXQCNRI4r4YUayeM2b0ZYLdzgKGl891jZBhOQIetlY7rU44kPpV1AA3/8wGDwNFKduIQZZ/qJYzg==} + peerDependencies: + svelte: ^5.0.0 + + '@immich/ui@0.59.0': + resolution: {integrity: sha512-7yxvyhhd99T0AHhjMakp7c/U4n0jGAmRO5xpncsRASRvqZve/LAibjr6N5FJc5IAd222DROTMLn6imsxVfqfvg==} + peerDependencies: + svelte: ^5.0.0 + '@immich/ui@0.79.2': resolution: {integrity: sha512-tnpYhYHrjrFJK18QglRMzPUtHv6q5V6tW38HiAraQJBv7MCg+yaJDrdF8omM2L5F311FGlv1PZLJYvmR4e49PA==} peerDependencies: @@ -3751,6 +3791,12 @@ packages: '@nestjs/websockets': optional: true + '@nestjs/event-emitter@3.1.0': + resolution: {integrity: sha512-DOY/4XBGyIjYyOJKkO6jl1kzFE0ZfX0wV+M2HR5NWymPT9Z0zdCEcZGxTXXkoMRwPtglnvCGJALSjOpXPIcM3g==} + peerDependencies: + '@nestjs/common': ^10.0.0 || ^11.0.0 + '@nestjs/core': ^10.0.0 || ^11.0.0 + '@nestjs/mapped-types@2.1.1': resolution: {integrity: sha512-SCCoMEJ6jdeI5h/N+KCVF1+pmg/hmEkNA5nHTS8Gvww7T/LCl4o1gFLinw2iQ60w7slFkszHcGLKGdazVI4F8A==} peerDependencies: @@ -3881,12 +3927,24 @@ packages: peerDependencies: '@opentelemetry/api': ^1.9.0 + '@opentelemetry/context-async-hooks@2.7.0': + resolution: {integrity: sha512-MWXggArM+Y11mPS8VOrqxOj+YMGQSRuvhM91eSBX4xFpJa05mpkeVvM8pPux5ElkEjV5RMgrkisrlP/R83SpBQ==} + engines: {node: ^18.19.0 || >=20.6.0} + peerDependencies: + '@opentelemetry/api': '>=1.0.0 <1.10.0' + '@opentelemetry/context-async-hooks@2.7.1': resolution: {integrity: sha512-OPFBYuXEn1E4ja3Y6eeA7O+ZnLBNcXTV5Cgsn1VaqBZ6hC5FnpZPLBNme1LJY8ZtF4aOujPKFoeWN4ik487KuQ==} engines: {node: ^18.19.0 || >=20.6.0} peerDependencies: '@opentelemetry/api': '>=1.0.0 <1.10.0' + '@opentelemetry/core@2.7.0': + resolution: {integrity: sha512-DT12SXVwV2eoJrGf4nnsvZojxxeQo+LlNAsoYGRRObPWTeN6APiqZ2+nqDCQDvQX40eLi1AePONS0onoASp3yQ==} + engines: {node: ^18.19.0 || >=20.6.0} + peerDependencies: + '@opentelemetry/api': '>=1.0.0 <1.10.0' + '@opentelemetry/core@2.7.1': resolution: {integrity: sha512-QAqIj32AtK6+pEVNG7EOVxHdE06RP+FM5qpiEJ4RtDcFIqKUZHYhl7/7UY5efhwmwNAg7j8QbJVBLxMerc0+gw==} engines: {node: ^18.19.0 || >=20.6.0} @@ -4029,6 +4087,12 @@ packages: resolution: {integrity: sha512-VCghU1JYs/4gP6Gqf/xro9MEsZ7LrMv2uONVsaESKL38ZOB9BqnI98FfS23wjMnHlpuE+TTaWSoAVNpTwYXzjw==} engines: {node: ^18.19.0 || >=20.6.0} + '@opentelemetry/resources@2.7.0': + resolution: {integrity: sha512-K+oi0hNMv94EpZbnW3eyu2X6SGVpD3O5DhG2NIp65Hc7lhAj9brRXTAVzh3wB82+q3ThakEf7Zd7RsFUqcTc7A==} + engines: {node: ^18.19.0 || >=20.6.0} + peerDependencies: + '@opentelemetry/api': '>=1.3.0 <1.10.0' + '@opentelemetry/resources@2.7.1': resolution: {integrity: sha512-DeT6KKolmC4e/dRQvMQ/RwlnzhaqeiFOXY5ngoOPJ07GgVVKxZOg9EcrNZb5aTzUn+iCrJldAgOfQm1O/QfPAQ==} engines: {node: ^18.19.0 || >=20.6.0} @@ -4041,6 +4105,12 @@ packages: peerDependencies: '@opentelemetry/api': '>=1.4.0 <1.10.0' + '@opentelemetry/sdk-metrics@2.7.0': + resolution: {integrity: sha512-Vd7h95av/LYRsAVN7wbprvvJnHkq7swMXAo7Uad0Uxf9jl6NSReLa0JNivrcc5BVIx/vl2t+cgdVQQbnVhsR9w==} + engines: {node: ^18.19.0 || >=20.6.0} + peerDependencies: + '@opentelemetry/api': '>=1.9.0 <1.10.0' + '@opentelemetry/sdk-metrics@2.7.1': resolution: {integrity: sha512-MpDJdkiFDs3Pm1RHO3KByuZbuBdJEXEAkiC0+yJdsZGVCdf1RpHR6n+LHDcS7ffmfrt5kVCzJSCfm4z2C7v0uQ==} engines: {node: ^18.19.0 || >=20.6.0} @@ -5097,6 +5167,14 @@ packages: peerDependencies: vite: ^5.2.0 || ^6 || ^7 || ^8 + '@tanstack/query-core@5.100.9': + resolution: {integrity: sha512-SJSFw1S8+kQ0+knv/XGfrbocWoAlT7vDKsSImtLx3ZPQmEcR46hkDjLSvynSy25N8Ms4tIEini1FuBd5k7IscQ==} + + '@tanstack/svelte-query@6.1.28': + resolution: {integrity: sha512-B4uh/fvn+t67LyWzY8Sb+yqyxJS2hc27Nwf+bfz7vy+ilzfJIHORoCm9/6Arsg4pdH8DCBMLMWZTvMgvSUd/pg==} + peerDependencies: + svelte: ^5.25.0 + '@testing-library/dom@10.4.1': resolution: {integrity: sha512-o4PXJQidqJl82ckFaXUeoAW+XysPLauYI43Abki5hABd853iMhitooc6znOnczgbTYmEP6U6/y1ZyKAIsvMKGg==} engines: {node: '>=18'} @@ -6209,6 +6287,10 @@ packages: resolution: {integrity: sha512-cU8v/EGSrnH+HnxV2z0J7/blxH8gq7Xh2JFT6Aroax7UohdmiJJlxApMxtKfuI7z68NvvVcmR78k2LbT6efhRg==} engines: {node: '>= 18'} + better-sqlite3@12.9.0: + resolution: {integrity: sha512-wqUv4Gm3toFpHDQmaKD4QhZm3g1DjUBI0yzS4UBl6lElUmXFYdTQmmEDpAFa5o8FiFiymURypEnfVHzILKaxqQ==} + engines: {node: 20.x || 22.x || 23.x || 24.x || 25.x} + big.js@5.2.2: resolution: {integrity: sha512-vyL2OymJxmarO8gxMr0mhChsO9QGwhynfuu4+MHTAW6czfq9humCB7rKpUjDd9YUiDPU4mzpyupFSvOClAwbmQ==} @@ -6216,6 +6298,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.18.1: resolution: {integrity: sha512-KkemzKFH4T3gt3H+P86JcnAWExjByv/6vlwjm/BoCwTPHu03yiCdxbghdJLvFReQTe0acCAiRcKfmixxD6XvlA==} engines: {node: '>=20'} @@ -6479,6 +6564,12 @@ packages: cjs-module-lexer@2.2.0: resolution: {integrity: sha512-4bHTS2YuzUvtoLjdy+98ykbNB5jS0+07EvFNXerqZQJ89F7DI6ET7OQo/HJuW6K0aVsKA9hj9/RVb2kQVOrPDQ==} + class-transformer@0.5.1: + resolution: {integrity: sha512-SQa1Ws6hUbfC98vKGxZH3KFY0Y1lm5Zm0SY8XX9zbK7FJCyVEac3ATW0RIpwzW+oOfmHE5PMPufDG9hCfoEOMw==} + + class-validator@0.14.4: + resolution: {integrity: sha512-AwNusCCam51q703dW82x95tOqQp6oC9HNUl724KxJJOfnKscI8dOloXFgyez7LbTTKWuRBA37FScqVbJEoq8Yw==} + clean-css@5.3.3: resolution: {integrity: sha512-D5J+kHaVb/wKSFcyyV75uCn8fiY4sV38XJoe4CUyGQ+mOU/fMVYUdH1hJC+CJQ5uY3EnW27SbJYS4X8BiLrAFg==} engines: {node: '>= 10.0'} @@ -6807,10 +6898,17 @@ 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'} + cronstrue@3.14.0: + resolution: {integrity: sha512-XnW4vuK/jPJjmTyDWiej1Zq36Od7ITwxaV2O1pzHZuyMVvdy7NAvyvIBzybt+idqSpfqYuoDG7uf/ocGtJVWxA==} + hasBin: true + cross-spawn@7.0.6: resolution: {integrity: sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==} engines: {node: '>= 8'} @@ -7732,10 +7830,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==} @@ -7746,19 +7850,40 @@ packages: resolution: {integrity: sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==} engines: {node: '>=0.8.x'} + eventsource-client@1.2.0: + resolution: {integrity: sha512-kDI75RSzO3TwyG/K9w1ap8XwqSPcwi6jaMkNulfVeZmSeUM49U8kUzk1s+vKNt0tGrXgK47i+620Yasn1ccFiw==} + engines: {node: '>=18.0.0'} + + eventsource-parser@3.0.6: + resolution: {integrity: sha512-Vo1ab+QXPzZ4tCa8SwIHJFaSzy4R6SHf7BY79rFBDf0idraZWAkYrDjDj8uWaSm3S2TK+hJ7/t1CEmZ7jXw+pg==} + engines: {node: '>=18.0.0'} + execa@5.1.1: resolution: {integrity: sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==} engines: {node: '>=10'} + exiftool-vendored.exe@13.57.0: + resolution: {integrity: sha512-9ENCWzUiFy6F/O4jSX50ygSGrTOtvoqJFWE0zAOl7VL/EFooLWNF0LkaNSox0ibbIsQz5rWSKi0TPlEbF4qBIw==} + os: [win32] + exiftool-vendored.exe@13.58.0: resolution: {integrity: sha512-pV7SjQeOu4Q77DWuyF+hlRYWVlRcSAqfqTTujBZeGUy/Q9+RPAy877YgSZIxKOYW1TxmmL8KyBGxaG0JKYG8BQ==} os: [win32] + exiftool-vendored.pl@13.57.0: + resolution: {integrity: sha512-7HYhrIygbfKD+E/sUF9L8YEs7qCEFLFWKoeevJllnD9jxVvZ09tfFsjbBPQ7SAgGwWSHW//SVULFHLgrO8JsBw==} + os: ['!win32'] + hasBin: true + exiftool-vendored.pl@13.58.0: resolution: {integrity: sha512-+Z2xhZrYLMu/anO/s14AaS/K5HMJ5Cw9C3KefIeYNpkZRN4RRBJHm7R34yjj9Pv+elqYRZrQV9NcqvkBLn/68w==} os: ['!win32'] hasBin: true + exiftool-vendored@35.19.0: + resolution: {integrity: sha512-c7/W5VA0f2XKllRgFSBOoTSRMlRVn13QT/TudOS3RN64VRfcj51vQQcRwtmdwYuRrzRf7lsh6gCQpmm3vr8Lww==} + engines: {node: '>=20.0.0'} + exiftool-vendored@35.20.0: resolution: {integrity: sha512-Yn66dSBaWGcUaSbm5Nl4G28rxtceLlWf4PstqJMbLix9sN7w0okWHPEvdudiP56Q5Cjl7v3TLyKKwowUFlbD8g==} engines: {node: '>=20.0.0'} @@ -7872,6 +7997,9 @@ packages: resolution: {integrity: sha512-Ievi/yy8DS3ygGvT47PjSfdFoX+2isQueoYP1cntFW1JLYAuS4GD7NUPGg4zv2iZfV52uDyk5w5Z0TdpRS6Q1g==} 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'} @@ -8913,6 +9041,10 @@ packages: resolution: {integrity: sha512-nbD8lB9EB3wNdMhOCdx5Li8DxnLbvKByylRLcJ1h+4SkrowVeECAyZlyiKMThF7xFdRz0jSQ2MoJr+wXux2y0Q==} engines: {node: '>=20.0.0'} + kysely@0.28.2: + resolution: {integrity: sha512-4YAVLoF0Sf0UTqlhgQMFU9iQECdah7n+13ANkiuVfRvlK+uI0Etbgd7bVP36dKlG+NXWbhGua8vnGt+sdhvT7A==} + engines: {node: '>=18.0.0'} + latest-version@7.0.0: resolution: {integrity: sha512-KvNT4XqAMzdcL6ka6Tl3i2lYeFDgXNCuIX+xNx6ZMVR1dFq+idXd9FLKNMOIx0t9mJ9/HudyX4oZWXZQ0UJHeg==} engines: {node: '>=14.16'} @@ -8941,6 +9073,9 @@ packages: resolution: {integrity: sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==} engines: {node: '>= 0.8.0'} + libphonenumber-js@1.12.43: + resolution: {integrity: sha512-5n+HnmkNpgZCfaNVxrTGZHr6Lhv3gd0UtbD5lrzun3T2YNyVvCuJz9vkap2E0YWZWU1XF+0XljYAkrAJBbwbrg==} + lightningcss-android-arm64@1.32.0: resolution: {integrity: sha512-YK7/ClTt4kAK0vo6w3X+Pnm0D2cf2vPHbhOXdoNti1Ga0al1P4TBZhwjATvjNwLEBCnKvjJc2jQgHXH0NEwlAg==} engines: {node: '>= 12.0.0'} @@ -10747,6 +10882,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==} @@ -11739,6 +11877,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-csstree@0.3.1: resolution: {integrity: sha512-v147gLOR+E+9H4dNaP9rBeS/S/CTQJMRItlX9jLOXjdBGfSRauLwiz7LBCViaQmn6URXIlOdN6iMzSzOaeoUUw==} engines: {node: '>=18.18'} @@ -11909,6 +12051,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==} @@ -11977,6 +12122,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'} @@ -12855,6 +13003,9 @@ packages: resolution: {integrity: sha512-CzhO+pFNo8ajLM2d2IW/R93ipy99LWjtwblvC1RsoSUMZgyLbYFr221TnSNT7GjGdYui6P459mw9JH/g/zW2ug==} engines: {node: '>=18'} + yup@1.7.1: + resolution: {integrity: sha512-GKHFX2nXul2/4Dtfxhozv701jLQHdf6J34YDh2cEkpqoo8le5Mg6/LrdseVLrFarmFygZTlfIhHx/QKfb/QWXw==} + zimmerframe@1.1.4: resolution: {integrity: sha512-B58NGBEoc8Y9MWWCQGl/gq9xBCe4IiKM0a2x7GZdQKOW5Exr8S1W24J6OgM1njK8xCRGvAJIL/MxXHf6SkmQKQ==} @@ -15730,10 +15881,66 @@ snapshots: dependencies: '@fortawesome/fontawesome-common-types': 7.2.0 - '@golevelup/nestjs-discovery@5.0.0(@nestjs/common@11.1.21(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.21)': + '@futo-org/backups-api-client@0.1.72': dependencies: - '@nestjs/common': 11.1.21(reflect-metadata@0.2.2)(rxjs@7.8.2) - '@nestjs/core': 11.1.21(@nestjs/common@11.1.21(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/platform-express@11.1.21)(@nestjs/websockets@11.1.21)(reflect-metadata@0.2.2)(rxjs@7.8.2) + '@oazapfts/runtime': 1.2.0 + + '@futo-org/backups-orchestrator-api@0.1.72(@nestjs/common@11.1.21(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.21)(@nestjs/platform-socket.io@11.1.21)(@nestjs/schedule@6.1.3(@nestjs/common@11.1.21(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.21))(@nestjs/websockets@11.1.21)(reflect-metadata@0.2.2)': + dependencies: + '@futo-org/backups-api-client': 0.1.72 + '@futo-org/restic-wrapper': 1.2.1 + '@nestjs/common': 11.1.21(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2)(rxjs@7.8.2) + '@nestjs/core': 11.1.21(@nestjs/common@11.1.21(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/platform-express@11.1.21)(@nestjs/websockets@11.1.21)(reflect-metadata@0.2.2)(rxjs@7.8.2) + '@nestjs/event-emitter': 3.1.0(@nestjs/common@11.1.21(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.21) + '@nestjs/platform-socket.io': 11.1.21(@nestjs/common@11.1.21(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/websockets@11.1.21)(rxjs@7.8.2) + '@nestjs/schedule': 6.1.3(@nestjs/common@11.1.21(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.21) + '@nestjs/websockets': 11.1.21(@nestjs/common@11.1.21(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.21)(@nestjs/platform-socket.io@11.1.21)(reflect-metadata@0.2.2)(rxjs@7.8.2) + better-sqlite3: 12.9.0 + class-validator: 0.14.4 + cookie: 1.1.1 + cron: 4.4.0 + event-iterator: 2.0.0 + eventsource-client: 1.2.0 + express: 5.2.1 + kysely: 0.28.2 + nestjs-kysely: 3.1.2(@nestjs/common@11.1.21(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.21)(kysely@0.28.2)(reflect-metadata@0.2.2) + openid-client: 6.8.4 + rxjs: 7.8.2 + socket.io: 4.8.3 + tail: 2.2.6 + transitivePeerDependencies: + - bufferutil + - reflect-metadata + - supports-color + - utf-8-validate + + '@futo-org/backups-orchestrator-ui@0.1.72(@sveltejs/kit@2.60.1(@opentelemetry/api@1.9.1)(@sveltejs/vite-plugin-svelte@7.1.2(svelte@5.55.8(@typescript-eslint/types@8.59.4))(vite@8.0.13(@types/node@24.12.4)(esbuild@0.28.0)(jiti@2.7.0)(sass@1.99.0)(terser@5.47.1)(tsx@4.22.3)(yaml@2.9.0)))(svelte@5.55.8(@typescript-eslint/types@8.59.4))(typescript@6.0.3)(vite@8.0.13(@types/node@24.12.4)(esbuild@0.28.0)(jiti@2.7.0)(sass@1.99.0)(terser@5.47.1)(tsx@4.22.3)(yaml@2.9.0)))(svelte@5.55.8(@typescript-eslint/types@8.59.4))': + dependencies: + '@futo-org/backups-api-client': 0.1.72 + '@immich/ui': 0.59.0(@sveltejs/kit@2.60.1(@opentelemetry/api@1.9.1)(@sveltejs/vite-plugin-svelte@7.1.2(svelte@5.55.8(@typescript-eslint/types@8.59.4))(vite@8.0.13(@types/node@24.12.4)(esbuild@0.28.0)(jiti@2.7.0)(sass@1.99.0)(terser@5.47.1)(tsx@4.22.3)(yaml@2.9.0)))(svelte@5.55.8(@typescript-eslint/types@8.59.4))(typescript@6.0.3)(vite@8.0.13(@types/node@24.12.4)(esbuild@0.28.0)(jiti@2.7.0)(sass@1.99.0)(terser@5.47.1)(tsx@4.22.3)(yaml@2.9.0)))(svelte@5.55.8(@typescript-eslint/types@8.59.4)) + '@mdi/js': 7.4.47 + '@oazapfts/runtime': 1.2.0 + '@tanstack/svelte-query': 6.1.28(svelte@5.55.8(@typescript-eslint/types@8.59.4)) + cron-validate: 1.5.3 + cronstrue: 3.14.0 + lodash.debounce: 4.0.8 + luxon: 3.7.2 + socket.io-client: 4.8.3 + svelte: 5.55.8(@typescript-eslint/types@8.59.4) + transitivePeerDependencies: + - '@sveltejs/kit' + - bufferutil + - supports-color + - utf-8-validate + + '@futo-org/restic-wrapper@1.2.1': + dependencies: + zod: 4.3.6 + + '@golevelup/nestjs-discovery@5.0.0(@nestjs/common@11.1.21(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.21)': + dependencies: + '@nestjs/common': 11.1.21(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2)(rxjs@7.8.2) + '@nestjs/core': 11.1.21(@nestjs/common@11.1.21(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/platform-express@11.1.21)(@nestjs/websockets@11.1.21)(reflect-metadata@0.2.2)(rxjs@7.8.2) lodash: 4.18.1 '@grpc/grpc-js@1.14.3': @@ -15892,6 +16099,26 @@ snapshots: pg-connection-string: 2.13.0 postgres: 3.4.9 + '@immich/svelte-markdown-preprocess@0.1.0(svelte@5.55.8(@typescript-eslint/types@8.59.4))': + dependencies: + svelte: 5.55.8(@typescript-eslint/types@8.59.4) + + '@immich/ui@0.59.0(@sveltejs/kit@2.60.1(@opentelemetry/api@1.9.1)(@sveltejs/vite-plugin-svelte@7.1.2(svelte@5.55.8(@typescript-eslint/types@8.59.4))(vite@8.0.13(@types/node@24.12.4)(esbuild@0.28.0)(jiti@2.7.0)(sass@1.99.0)(terser@5.47.1)(tsx@4.22.3)(yaml@2.9.0)))(svelte@5.55.8(@typescript-eslint/types@8.59.4))(typescript@6.0.3)(vite@8.0.13(@types/node@24.12.4)(esbuild@0.28.0)(jiti@2.7.0)(sass@1.99.0)(terser@5.47.1)(tsx@4.22.3)(yaml@2.9.0)))(svelte@5.55.8(@typescript-eslint/types@8.59.4))': + dependencies: + '@immich/svelte-markdown-preprocess': 0.1.0(svelte@5.55.8(@typescript-eslint/types@8.59.4)) + '@internationalized/date': 3.12.1 + '@mdi/js': 7.4.47 + bits-ui: 2.18.1(@internationalized/date@3.12.1)(@sveltejs/kit@2.60.1(@opentelemetry/api@1.9.1)(@sveltejs/vite-plugin-svelte@7.1.2(svelte@5.55.8(@typescript-eslint/types@8.59.4))(vite@8.0.13(@types/node@24.12.4)(esbuild@0.28.0)(jiti@2.7.0)(sass@1.99.0)(terser@5.47.1)(tsx@4.22.3)(yaml@2.9.0)))(svelte@5.55.8(@typescript-eslint/types@8.59.4))(typescript@6.0.3)(vite@8.0.13(@types/node@24.12.4)(esbuild@0.28.0)(jiti@2.7.0)(sass@1.99.0)(terser@5.47.1)(tsx@4.22.3)(yaml@2.9.0)))(svelte@5.55.8(@typescript-eslint/types@8.59.4)) + luxon: 3.7.2 + simple-icons: 16.20.0 + svelte: 5.55.8(@typescript-eslint/types@8.59.4) + svelte-highlight: 7.9.0 + tailwind-merge: 3.6.0 + tailwind-variants: 3.2.2(tailwind-merge@3.6.0)(tailwindcss@4.3.0) + tailwindcss: 4.3.0 + transitivePeerDependencies: + - '@sveltejs/kit' + '@immich/ui@0.79.2(@sveltejs/kit@2.60.1(@opentelemetry/api@1.9.1)(@sveltejs/vite-plugin-svelte@7.1.2(svelte@5.55.8(@typescript-eslint/types@8.59.4))(vite@8.0.13(@types/node@24.12.4)(esbuild@0.28.0)(jiti@2.7.0)(sass@1.99.0)(terser@5.47.1)(tsx@4.22.3)(yaml@2.9.0)))(svelte@5.55.8(@typescript-eslint/types@8.59.4))(typescript@6.0.3)(vite@8.0.13(@types/node@24.12.4)(esbuild@0.28.0)(jiti@2.7.0)(sass@1.99.0)(terser@5.47.1)(tsx@4.22.3)(yaml@2.9.0)))(svelte@5.55.8(@typescript-eslint/types@8.59.4))': dependencies: '@internationalized/date': 3.12.1 @@ -16437,17 +16664,17 @@ snapshots: '@tybys/wasm-util': 0.10.2 optional: true - '@nestjs/bull-shared@11.0.4(@nestjs/common@11.1.21(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.21)': + '@nestjs/bull-shared@11.0.4(@nestjs/common@11.1.21(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.21)': dependencies: - '@nestjs/common': 11.1.21(reflect-metadata@0.2.2)(rxjs@7.8.2) - '@nestjs/core': 11.1.21(@nestjs/common@11.1.21(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/platform-express@11.1.21)(@nestjs/websockets@11.1.21)(reflect-metadata@0.2.2)(rxjs@7.8.2) + '@nestjs/common': 11.1.21(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2)(rxjs@7.8.2) + '@nestjs/core': 11.1.21(@nestjs/common@11.1.21(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/platform-express@11.1.21)(@nestjs/websockets@11.1.21)(reflect-metadata@0.2.2)(rxjs@7.8.2) tslib: 2.8.1 - '@nestjs/bullmq@11.0.4(@nestjs/common@11.1.21(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.21)(bullmq@5.76.10)': + '@nestjs/bullmq@11.0.4(@nestjs/common@11.1.21(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.21)(bullmq@5.76.10)': dependencies: - '@nestjs/bull-shared': 11.0.4(@nestjs/common@11.1.21(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.21) - '@nestjs/common': 11.1.21(reflect-metadata@0.2.2)(rxjs@7.8.2) - '@nestjs/core': 11.1.21(@nestjs/common@11.1.21(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/platform-express@11.1.21)(@nestjs/websockets@11.1.21)(reflect-metadata@0.2.2)(rxjs@7.8.2) + '@nestjs/bull-shared': 11.0.4(@nestjs/common@11.1.21(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.21) + '@nestjs/common': 11.1.21(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2)(rxjs@7.8.2) + '@nestjs/core': 11.1.21(@nestjs/common@11.1.21(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/platform-express@11.1.21)(@nestjs/websockets@11.1.21)(reflect-metadata@0.2.2)(rxjs@7.8.2) bullmq: 5.76.10 tslib: 2.8.1 @@ -16489,7 +16716,7 @@ snapshots: - uglify-js - webpack-cli - '@nestjs/common@11.1.21(reflect-metadata@0.2.2)(rxjs@7.8.2)': + '@nestjs/common@11.1.21(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2)(rxjs@7.8.2)': dependencies: file-type: 21.3.4 iterare: 1.2.1 @@ -16498,12 +16725,15 @@ snapshots: rxjs: 7.8.2 tslib: 2.8.1 uid: 2.0.2 + optionalDependencies: + class-transformer: 0.5.1 + class-validator: 0.14.4 transitivePeerDependencies: - supports-color - '@nestjs/core@11.1.21(@nestjs/common@11.1.21(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/platform-express@11.1.21)(@nestjs/websockets@11.1.21)(reflect-metadata@0.2.2)(rxjs@7.8.2)': + '@nestjs/core@11.1.21(@nestjs/common@11.1.21(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/platform-express@11.1.21)(@nestjs/websockets@11.1.21)(reflect-metadata@0.2.2)(rxjs@7.8.2)': dependencies: - '@nestjs/common': 11.1.21(reflect-metadata@0.2.2)(rxjs@7.8.2) + '@nestjs/common': 11.1.21(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 @@ -16513,18 +16743,27 @@ snapshots: tslib: 2.8.1 uid: 2.0.2 optionalDependencies: - '@nestjs/platform-express': 11.1.21(@nestjs/common@11.1.21(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.21) - '@nestjs/websockets': 11.1.21(@nestjs/common@11.1.21(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.21)(@nestjs/platform-socket.io@11.1.21)(reflect-metadata@0.2.2)(rxjs@7.8.2) + '@nestjs/platform-express': 11.1.21(@nestjs/common@11.1.21(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.21) + '@nestjs/websockets': 11.1.21(@nestjs/common@11.1.21(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.21)(@nestjs/platform-socket.io@11.1.21)(reflect-metadata@0.2.2)(rxjs@7.8.2) - '@nestjs/mapped-types@2.1.1(@nestjs/common@11.1.21(reflect-metadata@0.2.2)(rxjs@7.8.2))(reflect-metadata@0.2.2)': + '@nestjs/event-emitter@3.1.0(@nestjs/common@11.1.21(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.21)': dependencies: - '@nestjs/common': 11.1.21(reflect-metadata@0.2.2)(rxjs@7.8.2) + '@nestjs/common': 11.1.21(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2)(rxjs@7.8.2) + '@nestjs/core': 11.1.21(@nestjs/common@11.1.21(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/platform-express@11.1.21)(@nestjs/websockets@11.1.21)(reflect-metadata@0.2.2)(rxjs@7.8.2) + eventemitter2: 6.4.9 + + '@nestjs/mapped-types@2.1.1(@nestjs/common@11.1.21(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.21(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.14.4 - '@nestjs/platform-express@11.1.21(@nestjs/common@11.1.21(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.21)': + '@nestjs/platform-express@11.1.21(@nestjs/common@11.1.21(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.21)': dependencies: - '@nestjs/common': 11.1.21(reflect-metadata@0.2.2)(rxjs@7.8.2) - '@nestjs/core': 11.1.21(@nestjs/common@11.1.21(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/platform-express@11.1.21)(@nestjs/websockets@11.1.21)(reflect-metadata@0.2.2)(rxjs@7.8.2) + '@nestjs/common': 11.1.21(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2)(rxjs@7.8.2) + '@nestjs/core': 11.1.21(@nestjs/common@11.1.21(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/platform-express@11.1.21)(@nestjs/websockets@11.1.21)(reflect-metadata@0.2.2)(rxjs@7.8.2) cors: 2.8.6 express: 5.2.1 multer: 2.1.1 @@ -16533,10 +16772,10 @@ snapshots: transitivePeerDependencies: - supports-color - '@nestjs/platform-socket.io@11.1.21(@nestjs/common@11.1.21(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/websockets@11.1.21)(rxjs@7.8.2)': + '@nestjs/platform-socket.io@11.1.21(@nestjs/common@11.1.21(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/websockets@11.1.21)(rxjs@7.8.2)': dependencies: - '@nestjs/common': 11.1.21(reflect-metadata@0.2.2)(rxjs@7.8.2) - '@nestjs/websockets': 11.1.21(@nestjs/common@11.1.21(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.21)(@nestjs/platform-socket.io@11.1.21)(reflect-metadata@0.2.2)(rxjs@7.8.2) + '@nestjs/common': 11.1.21(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2)(rxjs@7.8.2) + '@nestjs/websockets': 11.1.21(@nestjs/common@11.1.21(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.21)(@nestjs/platform-socket.io@11.1.21)(reflect-metadata@0.2.2)(rxjs@7.8.2) rxjs: 7.8.2 socket.io: 4.8.3 tslib: 2.8.1 @@ -16545,10 +16784,10 @@ snapshots: - supports-color - utf-8-validate - '@nestjs/schedule@6.1.3(@nestjs/common@11.1.21(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.21)': + '@nestjs/schedule@6.1.3(@nestjs/common@11.1.21(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.21)': dependencies: - '@nestjs/common': 11.1.21(reflect-metadata@0.2.2)(rxjs@7.8.2) - '@nestjs/core': 11.1.21(@nestjs/common@11.1.21(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/platform-express@11.1.21)(@nestjs/websockets@11.1.21)(reflect-metadata@0.2.2)(rxjs@7.8.2) + '@nestjs/common': 11.1.21(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2)(rxjs@7.8.2) + '@nestjs/core': 11.1.21(@nestjs/common@11.1.21(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/platform-express@11.1.21)(@nestjs/websockets@11.1.21)(reflect-metadata@0.2.2)(rxjs@7.8.2) cron: 4.4.0 '@nestjs/schematics@11.1.0(chokidar@4.0.3)(prettier@3.8.3)(typescript@5.9.3)': @@ -16577,38 +16816,41 @@ snapshots: transitivePeerDependencies: - chokidar - '@nestjs/swagger@11.4.3(@nestjs/common@11.1.21(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.21)(reflect-metadata@0.2.2)(typescript@6.0.3)': + '@nestjs/swagger@11.4.3(@nestjs/common@11.1.21(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.21)(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2)(typescript@6.0.3)': dependencies: '@microsoft/tsdoc': 0.16.0 - '@nestjs/common': 11.1.21(reflect-metadata@0.2.2)(rxjs@7.8.2) - '@nestjs/core': 11.1.21(@nestjs/common@11.1.21(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/platform-express@11.1.21)(@nestjs/websockets@11.1.21)(reflect-metadata@0.2.2)(rxjs@7.8.2) - '@nestjs/mapped-types': 2.1.1(@nestjs/common@11.1.21(reflect-metadata@0.2.2)(rxjs@7.8.2))(reflect-metadata@0.2.2) + '@nestjs/common': 11.1.21(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2)(rxjs@7.8.2) + '@nestjs/core': 11.1.21(@nestjs/common@11.1.21(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/platform-express@11.1.21)(@nestjs/websockets@11.1.21)(reflect-metadata@0.2.2)(rxjs@7.8.2) + '@nestjs/mapped-types': 2.1.1(@nestjs/common@11.1.21(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.18.1 path-to-regexp: 8.4.2 reflect-metadata: 0.2.2 swagger-ui-dist: 5.32.6 typescript: 6.0.3 + optionalDependencies: + class-transformer: 0.5.1 + class-validator: 0.14.4 - '@nestjs/testing@11.1.21(@nestjs/common@11.1.21(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.21)(@nestjs/platform-express@11.1.21)': + '@nestjs/testing@11.1.21(@nestjs/common@11.1.21(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.21)(@nestjs/platform-express@11.1.21)': dependencies: - '@nestjs/common': 11.1.21(reflect-metadata@0.2.2)(rxjs@7.8.2) - '@nestjs/core': 11.1.21(@nestjs/common@11.1.21(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/platform-express@11.1.21)(@nestjs/websockets@11.1.21)(reflect-metadata@0.2.2)(rxjs@7.8.2) + '@nestjs/common': 11.1.21(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2)(rxjs@7.8.2) + '@nestjs/core': 11.1.21(@nestjs/common@11.1.21(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/platform-express@11.1.21)(@nestjs/websockets@11.1.21)(reflect-metadata@0.2.2)(rxjs@7.8.2) tslib: 2.8.1 optionalDependencies: - '@nestjs/platform-express': 11.1.21(@nestjs/common@11.1.21(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.21) + '@nestjs/platform-express': 11.1.21(@nestjs/common@11.1.21(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.21) - '@nestjs/websockets@11.1.21(@nestjs/common@11.1.21(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.21)(@nestjs/platform-socket.io@11.1.21)(reflect-metadata@0.2.2)(rxjs@7.8.2)': + '@nestjs/websockets@11.1.21(@nestjs/common@11.1.21(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.21)(@nestjs/platform-socket.io@11.1.21)(reflect-metadata@0.2.2)(rxjs@7.8.2)': dependencies: - '@nestjs/common': 11.1.21(reflect-metadata@0.2.2)(rxjs@7.8.2) - '@nestjs/core': 11.1.21(@nestjs/common@11.1.21(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/platform-express@11.1.21)(@nestjs/websockets@11.1.21)(reflect-metadata@0.2.2)(rxjs@7.8.2) + '@nestjs/common': 11.1.21(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2)(rxjs@7.8.2) + '@nestjs/core': 11.1.21(@nestjs/common@11.1.21(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/platform-express@11.1.21)(@nestjs/websockets@11.1.21)(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.21(@nestjs/common@11.1.21(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/websockets@11.1.21)(rxjs@7.8.2) + '@nestjs/platform-socket.io': 11.1.21(@nestjs/common@11.1.21(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/websockets@11.1.21)(rxjs@7.8.2) '@noble/hashes@1.4.0': {} @@ -16646,10 +16888,19 @@ snapshots: '@opentelemetry/core': 2.7.1(@opentelemetry/api@1.9.1) yaml: 2.9.0 + '@opentelemetry/context-async-hooks@2.7.0(@opentelemetry/api@1.9.1)': + dependencies: + '@opentelemetry/api': 1.9.1 + '@opentelemetry/context-async-hooks@2.7.1(@opentelemetry/api@1.9.1)': dependencies: '@opentelemetry/api': 1.9.1 + '@opentelemetry/core@2.7.0(@opentelemetry/api@1.9.1)': + dependencies: + '@opentelemetry/api': 1.9.1 + '@opentelemetry/semantic-conventions': 1.41.1 + '@opentelemetry/core@2.7.1(@opentelemetry/api@1.9.1)': dependencies: '@opentelemetry/api': 1.9.1 @@ -16850,6 +17101,12 @@ snapshots: '@opentelemetry/redis-common@0.38.3': {} + '@opentelemetry/resources@2.7.0(@opentelemetry/api@1.9.1)': + dependencies: + '@opentelemetry/api': 1.9.1 + '@opentelemetry/core': 2.7.0(@opentelemetry/api@1.9.1) + '@opentelemetry/semantic-conventions': 1.41.1 + '@opentelemetry/resources@2.7.1(@opentelemetry/api@1.9.1)': dependencies: '@opentelemetry/api': 1.9.1 @@ -16864,6 +17121,12 @@ snapshots: '@opentelemetry/resources': 2.7.1(@opentelemetry/api@1.9.1) '@opentelemetry/semantic-conventions': 1.41.1 + '@opentelemetry/sdk-metrics@2.7.0(@opentelemetry/api@1.9.1)': + dependencies: + '@opentelemetry/api': 1.9.1 + '@opentelemetry/core': 2.7.0(@opentelemetry/api@1.9.1) + '@opentelemetry/resources': 2.7.0(@opentelemetry/api@1.9.1) + '@opentelemetry/sdk-metrics@2.7.1(@opentelemetry/api@1.9.1)': dependencies: '@opentelemetry/api': 1.9.1 @@ -17762,6 +18025,13 @@ snapshots: tailwindcss: 4.3.0 vite: 8.0.13(@types/node@24.12.4)(esbuild@0.28.0)(jiti@2.7.0)(sass@1.99.0)(terser@5.47.1)(tsx@4.22.3)(yaml@2.9.0) + '@tanstack/query-core@5.100.9': {} + + '@tanstack/svelte-query@6.1.28(svelte@5.55.8(@typescript-eslint/types@8.59.4))': + dependencies: + '@tanstack/query-core': 5.100.9 + svelte: 5.55.8(@typescript-eslint/types@8.59.4) + '@testing-library/dom@10.4.1': dependencies: '@babel/code-frame': 7.29.0 @@ -19083,10 +19353,19 @@ snapshots: node-gyp: 12.3.0 node-gyp-build: 4.8.4 + better-sqlite3@12.9.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.18.1(@internationalized/date@3.12.1)(@sveltejs/kit@2.60.1(@opentelemetry/api@1.9.1)(@sveltejs/vite-plugin-svelte@7.1.2(svelte@5.55.8(@typescript-eslint/types@8.59.4))(vite@8.0.13(@types/node@24.12.4)(esbuild@0.28.0)(jiti@2.7.0)(sass@1.99.0)(terser@5.47.1)(tsx@4.22.3)(yaml@2.9.0)))(svelte@5.55.8(@typescript-eslint/types@8.59.4))(typescript@6.0.3)(vite@8.0.13(@types/node@24.12.4)(esbuild@0.28.0)(jiti@2.7.0)(sass@1.99.0)(terser@5.47.1)(tsx@4.22.3)(yaml@2.9.0)))(svelte@5.55.8(@typescript-eslint/types@8.59.4)): dependencies: '@floating-ui/core': 1.7.5 @@ -19392,6 +19671,15 @@ snapshots: cjs-module-lexer@2.2.0: {} + class-transformer@0.5.1: + optional: true + + class-validator@0.14.4: + dependencies: + '@types/validator': 13.15.10 + libphonenumber-js: 1.12.43 + validator: 13.15.35 + clean-css@5.3.3: dependencies: source-map: 0.6.1 @@ -19701,11 +19989,17 @@ 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 luxon: 3.7.2 + cronstrue@3.14.0: {} + cross-spawn@7.0.6: dependencies: path-key: 3.1.1 @@ -20817,8 +21111,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: @@ -20829,6 +21127,12 @@ snapshots: events@3.3.0: {} + eventsource-client@1.2.0: + dependencies: + eventsource-parser: 3.0.6 + + eventsource-parser@3.0.6: {} + execa@5.1.1: dependencies: cross-spawn: 7.0.6 @@ -20841,11 +21145,27 @@ snapshots: signal-exit: 3.0.7 strip-final-newline: 2.0.0 + exiftool-vendored.exe@13.57.0: + optional: true + exiftool-vendored.exe@13.58.0: optional: true + exiftool-vendored.pl@13.57.0: {} + exiftool-vendored.pl@13.58.0: {} + exiftool-vendored@35.19.0: + dependencies: + '@photostructure/tz-lookup': 11.5.0 + '@types/luxon': 3.7.1 + batch-cluster: 17.3.1 + exiftool-vendored.pl: 13.57.0 + he: 1.2.0 + luxon: 3.7.2 + optionalDependencies: + exiftool-vendored.exe: 13.57.0 + exiftool-vendored@35.20.0: dependencies: '@photostructure/tz-lookup': 11.5.0 @@ -20857,8 +21177,7 @@ snapshots: optionalDependencies: exiftool-vendored.exe: 13.58.0 - expand-template@2.0.3: - optional: true + expand-template@2.0.3: {} expect-type@1.3.0: {} @@ -21028,6 +21347,8 @@ snapshots: transitivePeerDependencies: - supports-color + file-uri-to-path@1.0.0: {} + fill-range@7.1.1: dependencies: to-regex-range: 5.0.1 @@ -21238,8 +21559,7 @@ snapshots: dependencies: resolve-pkg-maps: 1.0.0 - github-from-package@0.0.0: - optional: true + github-from-package@0.0.0: {} github-slugger@1.5.0: {} @@ -22206,6 +22526,8 @@ snapshots: kysely@0.28.17: {} + kysely@0.28.2: {} + latest-version@7.0.0: dependencies: package-json: 8.1.1 @@ -22232,6 +22554,8 @@ snapshots: prelude-ls: 1.2.1 type-check: 0.4.0 + libphonenumber-js@1.12.43: {} + lightningcss-android-arm64@1.32.0: optional: true @@ -23178,8 +23502,7 @@ snapshots: nanoid@5.1.11: {} - napi-build-utils@2.0.0: - optional: true + napi-build-utils@2.0.0: {} natural-compare-lite@1.4.0: {} @@ -23200,12 +23523,12 @@ snapshots: neo-async@2.6.2: {} - nest-commander@3.20.1(@nestjs/common@11.1.21(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.21)(@types/inquirer@8.2.12)(@types/node@24.12.4)(typescript@6.0.3): + nest-commander@3.20.1(@nestjs/common@11.1.21(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.21)(@types/inquirer@8.2.12)(@types/node@24.12.4)(typescript@6.0.3): dependencies: '@fig/complete-commander': 3.2.0(commander@11.1.0) - '@golevelup/nestjs-discovery': 5.0.0(@nestjs/common@11.1.21(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.21) - '@nestjs/common': 11.1.21(reflect-metadata@0.2.2)(rxjs@7.8.2) - '@nestjs/core': 11.1.21(@nestjs/common@11.1.21(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/platform-express@11.1.21)(@nestjs/websockets@11.1.21)(reflect-metadata@0.2.2)(rxjs@7.8.2) + '@golevelup/nestjs-discovery': 5.0.0(@nestjs/common@11.1.21(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.21) + '@nestjs/common': 11.1.21(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2)(rxjs@7.8.2) + '@nestjs/core': 11.1.21(@nestjs/common@11.1.21(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/platform-express@11.1.21)(@nestjs/websockets@11.1.21)(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.3) @@ -23214,37 +23537,45 @@ snapshots: - '@types/node' - typescript - nestjs-cls@6.2.0(@nestjs/common@11.1.21(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.21)(reflect-metadata@0.2.2)(rxjs@7.8.2): + nestjs-cls@6.2.0(@nestjs/common@11.1.21(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.21)(reflect-metadata@0.2.2)(rxjs@7.8.2): dependencies: - '@nestjs/common': 11.1.21(reflect-metadata@0.2.2)(rxjs@7.8.2) - '@nestjs/core': 11.1.21(@nestjs/common@11.1.21(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/platform-express@11.1.21)(@nestjs/websockets@11.1.21)(reflect-metadata@0.2.2)(rxjs@7.8.2) + '@nestjs/common': 11.1.21(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2)(rxjs@7.8.2) + '@nestjs/core': 11.1.21(@nestjs/common@11.1.21(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/platform-express@11.1.21)(@nestjs/websockets@11.1.21)(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.21(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.21)(kysely@0.28.17)(reflect-metadata@0.2.2): + nestjs-kysely@3.1.2(@nestjs/common@11.1.21(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.21)(kysely@0.28.17)(reflect-metadata@0.2.2): dependencies: - '@nestjs/common': 11.1.21(reflect-metadata@0.2.2)(rxjs@7.8.2) - '@nestjs/core': 11.1.21(@nestjs/common@11.1.21(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/platform-express@11.1.21)(@nestjs/websockets@11.1.21)(reflect-metadata@0.2.2)(rxjs@7.8.2) + '@nestjs/common': 11.1.21(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2)(rxjs@7.8.2) + '@nestjs/core': 11.1.21(@nestjs/common@11.1.21(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/platform-express@11.1.21)(@nestjs/websockets@11.1.21)(reflect-metadata@0.2.2)(rxjs@7.8.2) kysely: 0.28.17 reflect-metadata: 0.2.2 tslib: 2.8.1 - nestjs-otel@8.0.3(@nestjs/common@11.1.21(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.21): + nestjs-kysely@3.1.2(@nestjs/common@11.1.21(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.21)(kysely@0.28.2)(reflect-metadata@0.2.2): dependencies: - '@nestjs/common': 11.1.21(reflect-metadata@0.2.2)(rxjs@7.8.2) - '@nestjs/core': 11.1.21(@nestjs/common@11.1.21(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/platform-express@11.1.21)(@nestjs/websockets@11.1.21)(reflect-metadata@0.2.2)(rxjs@7.8.2) + '@nestjs/common': 11.1.21(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2)(rxjs@7.8.2) + '@nestjs/core': 11.1.21(@nestjs/common@11.1.21(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/platform-express@11.1.21)(@nestjs/websockets@11.1.21)(reflect-metadata@0.2.2)(rxjs@7.8.2) + kysely: 0.28.2 + reflect-metadata: 0.2.2 + tslib: 2.8.1 + + nestjs-otel@8.0.3(@nestjs/common@11.1.21(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.21): + dependencies: + '@nestjs/common': 11.1.21(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2)(rxjs@7.8.2) + '@nestjs/core': 11.1.21(@nestjs/common@11.1.21(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/platform-express@11.1.21)(@nestjs/websockets@11.1.21)(reflect-metadata@0.2.2)(rxjs@7.8.2) '@opentelemetry/api': 1.9.1 '@opentelemetry/host-metrics': 0.38.3(@opentelemetry/api@1.9.1) tslib: 2.8.1 - nestjs-zod@5.4.0(@nestjs/common@11.1.21(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/swagger@11.4.3(@nestjs/common@11.1.21(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.21)(reflect-metadata@0.2.2)(typescript@6.0.3))(rxjs@7.8.2)(zod@4.3.6): + nestjs-zod@5.4.0(@nestjs/common@11.1.21(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/swagger@11.4.3(@nestjs/common@11.1.21(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.21)(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2)(typescript@6.0.3))(rxjs@7.8.2)(zod@4.3.6): dependencies: - '@nestjs/common': 11.1.21(reflect-metadata@0.2.2)(rxjs@7.8.2) + '@nestjs/common': 11.1.21(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.4.3(@nestjs/common@11.1.21(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.21)(reflect-metadata@0.2.2)(typescript@6.0.3) + '@nestjs/swagger': 11.4.3(@nestjs/common@11.1.21(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.21)(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2)(typescript@6.0.3) next-tick@1.1.0: {} @@ -23256,7 +23587,6 @@ snapshots: node-abi@3.92.0: dependencies: semver: 7.8.0 - optional: true node-abort-controller@3.1.1: {} @@ -24259,7 +24589,6 @@ snapshots: simple-get: 4.0.1 tar-fs: 2.1.4 tunnel-agent: 0.6.0 - optional: true prelude-ls@1.2.1: {} @@ -24334,6 +24663,8 @@ snapshots: transitivePeerDependencies: - supports-color + property-expr@2.0.6: {} + property-information@5.6.0: dependencies: xtend: 4.0.2 @@ -25166,15 +25497,13 @@ snapshots: signal-exit@4.1.0: {} - simple-concat@1.0.1: - optional: true + simple-concat@1.0.1: {} simple-get@4.0.1: dependencies: decompress-response: 6.0.0 once: 1.4.0 simple-concat: 1.0.1 - optional: true simple-icons@16.20.0: {} @@ -25657,6 +25986,8 @@ snapshots: tagged-tag@1.0.0: {} + tail@2.2.6: {} + tailwind-csstree@0.3.1: {} tailwind-merge@3.6.0: {} @@ -25881,6 +26212,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 @@ -25938,6 +26271,8 @@ snapshots: '@tokenizer/token': 0.3.0 ieee754: 1.2.1 + toposort@2.0.2: {} + totalist@3.0.1: {} tough-cookie@5.1.2: @@ -26022,7 +26357,6 @@ snapshots: tunnel-agent@0.6.0: dependencies: safe-buffer: 5.2.1 - optional: true tweetnacl@0.14.5: {} @@ -26910,6 +27244,13 @@ snapshots: yoctocolors@2.1.2: {} + 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 a848deca82..98295e70c1 100644 --- a/pnpm-workspace.yaml +++ b/pnpm-workspace.yaml @@ -8,6 +8,7 @@ packages: - web - .github - packages/* +dedupePeerDependents: false ignoredBuiltDependencies: - '@nestjs/core' - '@parcel/watcher' @@ -24,47 +25,47 @@ ignoredBuiltDependencies: - protobufjs - ssh2 - utimes +injectWorkspacePackages: true onlyBuiltDependencies: - - sharp - '@tailwindcss/oxide' - bcrypt + - better-sqlite3 + - sharp overrides: canvas: 3.2.3 sharp: ^0.34.5 # pending docusaurus 3.10.1 webpackbar: ^7.0.0 packageExtensions: - nestjs-kysely: + '@immich/ui': dependencies: - tslib: '*' - nestjs-otel: - dependencies: - tslib: '*' + tailwindcss: '>=4.1' + '@nestjs/swagger': + peerDependencies: + typescript: '*' '@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: '*' - '@nestjs/swagger': - peerDependencies: - typescript: '*' -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 3d074ba17f..87b2e0a26a 100644 --- a/server/Dockerfile +++ b/server/Dockerfile @@ -113,6 +113,9 @@ 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} +# TODO[YUCCA]: pin restic & put in correct place +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 7979e88dd3..2e8e5b66ad 100644 --- a/server/Dockerfile.dev +++ b/server/Dockerfile.dev @@ -27,9 +27,10 @@ ENTRYPOINT ["tini", "--", "/bin/bash", "-c"] FROM dev AS dev-container-server +# TODO[YUCCA]: pin restic & put in correct place 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 119a1ea603..aea5bd1ece 100644 --- a/server/package.json +++ b/server/package.json @@ -37,6 +37,7 @@ }, "dependencies": { "@extism/extism": "2.0.0-rc13", + "@futo-org/backups-orchestrator-api": "0.1.72", "@immich/plugin-sdk": "workspace:*", "@immich/sql-tools": "^0.5.1", "@nestjs/bullmq": "^11.0.1", diff --git a/server/src/app.module.ts b/server/src/app.module.ts index ae930762d0..a6ff7e45bd 100644 --- a/server/src/app.module.ts +++ b/server/src/app.module.ts @@ -1,3 +1,4 @@ +import { OrchestrationApiModule } from '@futo-org/backups-orchestrator-api/dist'; import { BullModule } from '@nestjs/bullmq'; import { Inject, Module, OnModuleDestroy, OnModuleInit } from '@nestjs/common'; import { APP_FILTER, APP_GUARD, APP_INTERCEPTOR, APP_PIPE } from '@nestjs/core'; @@ -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,11 +52,19 @@ 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(); +// TODO[YUCCA]: use IMMICH_ENV +const isYuccaDevelopmentMode = true; + const commonImports = [ ClsModule.forRoot(cls.config), KyselyModule.forRoot(getKyselyConfig(database.config)), @@ -102,14 +112,35 @@ export class BaseModule implements OnModuleInit, OnModuleDestroy { } @Module({ - imports: [...bullImports, ...commonImports, ScheduleModule.forRoot()], + imports: [ + ...bullImports, + ...commonImports, + ScheduleModule.forRoot(), + OrchestrationApiModule.forRoot({ + yuccaProductionApi: 'https://staging.fubar.computer', // TODO[YUCCA]: load from futo.cloud -> .well-known file + statePath: '/data/yucca', // TODO[YUCCA]: point to {immich_data_location}/yucca + requireWsAuth: true, + requireLock: true, + developmentMode: isYuccaDevelopmentMode, + }), + ], 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', // TODO[YUCCA]: load from futo.cloud -> .well-known file + statePath: '/data/yucca', // TODO[YUCCA]: point to {immich_data_location}/yucca + externalBaseUrl: 'https://my.immich.app', + requireWsAuth: true, + requireLock: true, + developmentMode: isYuccaDevelopmentMode, + }), + ], controllers: [MaintenanceWorkerController], providers: [ ConfigRepository, diff --git a/server/src/enum.ts b/server/src/enum.ts index 27cab3fb5e..1a41a774b0 100644 --- a/server/src/enum.ts +++ b/server/src/enum.ts @@ -920,6 +920,7 @@ export enum DatabaseLock { MaintenanceOperation = 621, MemoryCreation = 777, VersionCheck = 800, + YuccaModuleConfig = 900, } export enum MaintenanceAction { 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..583d866554 100644 --- a/server/src/maintenance/maintenance-worker.service.ts +++ b/server/src/maintenance/maintenance-worker.service.ts @@ -1,3 +1,4 @@ +import { EventsGateway } from '@futo-org/backups-orchestrator-api/dist'; import { Injectable, UnauthorizedException } from '@nestjs/common'; import { parse } from 'cookie'; import { NextFunction, Request, Response } from 'express'; @@ -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 fa92a6b0b7..4404395d90 100644 --- a/server/src/repositories/event.repository.ts +++ b/server/src/repositories/event.repository.ts @@ -1,3 +1,4 @@ +import { GatewayEvent as YuccaGatewayEvent } from '@futo-org/backups-orchestrator-api/dist/events/events.gateway'; import { Injectable } from '@nestjs/common'; import { ModuleRef, Reflector } from '@nestjs/core'; import _ from 'lodash'; @@ -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 b4a0fcc00a..fe685d941a 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 b733483aa8..91ac39d0c0 100644 --- a/server/src/services/index.ts +++ b/server/src/services/index.ts @@ -46,6 +46,7 @@ import { VersionService } from 'src/services/version.service'; import { ViewService } from 'src/services/view.service'; import { WorkflowExecutionService } from 'src/services/workflow-execution.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 = [ ViewService, WorkflowExecutionService, WorkflowService, + YuccaService, ]; diff --git a/server/src/services/library.service.ts b/server/src/services/library.service.ts index 085650be6f..e93416d8f7 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..9b589c6eb2 --- /dev/null +++ b/server/src/services/yucca.service.ts @@ -0,0 +1,113 @@ +import { EventsGateway, ModuleConfigRepository } from '@futo-org/backups-orchestrator-api/dist'; +import { GatewayEvent } from '@futo-org/backups-orchestrator-api/dist/events/events.gateway'; +import { Injectable, OnModuleDestroy, OnModuleInit, Optional } from '@nestjs/common'; +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 2fb37daaed..9145587bc3 100644 --- a/web/package.json +++ b/web/package.json @@ -25,6 +25,7 @@ }, "dependencies": { "@formatjs/icu-messageformat-parser": "^3.0.0", + "@futo-org/backups-orchestrator-ui": "0.1.72", "@immich/justified-layout-wasm": "^0.4.3", "@immich/sdk": "workspace:*", "@immich/ui": "^0.79.2", diff --git a/web/src/lib/components/maintenance/MaintenanceBackupCard.svelte b/web/src/lib/components/maintenance/MaintenanceBackupCard.svelte new file mode 100644 index 0000000000..c678c6a32f --- /dev/null +++ b/web/src/lib/components/maintenance/MaintenanceBackupCard.svelte @@ -0,0 +1,119 @@ + + + + + +
+ + {#if status === BackupFileStatus.OK} + + {:else if status === BackupFileStatus.DifferentVersion} + + {:else} + + {/if} + + {#if dateDisplay} + {dateDisplay} + {:else} + {$t('unknown_date')} + {/if} + {#if relativeTime} +
+
+ {relativeTime} +
+ {/if} +
+ + {#if actions} + + {@render actions()} + + {/if} +
+ + + + {filename} + + + {#if status === BackupFileStatus.UnknownVersion} + + {$t('admin.maintenance_restore_backup_unknown_version')} + + {:else if status === BackupFileStatus.DifferentVersion} + + {$t('admin.maintenance_restore_backup_different_version')} + + {/if} + + +
+ {$t('version')}: + {version ? `v${version}` : $t('unknown')} +
+
+ {$t('size')}: + {filesizeText[0]} {filesizeText[1]} +
+
+
+
+
diff --git a/web/src/lib/components/maintenance/MaintenanceBackupEntry.svelte b/web/src/lib/components/maintenance/MaintenanceBackupEntry.svelte index 219956269d..3658d9ad61 100644 --- a/web/src/lib/components/maintenance/MaintenanceBackupEntry.svelte +++ b/web/src/lib/components/maintenance/MaintenanceBackupEntry.svelte @@ -1,12 +1,8 @@ + + + {data.meta.title} + + + + + goto('/')} /> + + diff --git a/web/src/routes/(user)/backups/+page.ts b/web/src/routes/(user)/backups/+page.ts new file mode 100644 index 0000000000..d42f20a32f --- /dev/null +++ b/web/src/routes/(user)/backups/+page.ts @@ -0,0 +1,12 @@ +import { authenticate } from '$lib/utils/auth'; +import type { PageLoad } from './$types'; + +export const load = (async ({ url }) => { + await authenticate(url); + + return { + meta: { + title: 'Backups', + }, + }; +}) satisfies PageLoad; diff --git a/web/src/routes/maintenance/+page.svelte b/web/src/routes/maintenance/+page.svelte index c5fbde28ec..746fd66682 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 '@futo-org/backups-orchestrator-ui'; import { t } from 'svelte-i18n'; import type { PageData } from './$types'; @@ -29,6 +30,11 @@ action: MaintenanceAction.End, }); + const startRestore = () => + handleSetMaintenanceMode({ + action: MaintenanceAction.SelectDatabaseRestore, + }); + const error = $derived( $status?.error ?.split('\n') @@ -37,58 +43,63 @@ ); - -
- {#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} -
-
+
+
+ diff --git a/web/src/routes/maintenance/MaintenanceRestoreFlow.svelte b/web/src/routes/maintenance/MaintenanceRestoreFlow.svelte index 97119ea2f9..4eb9095716 100644 --- a/web/src/routes/maintenance/MaintenanceRestoreFlow.svelte +++ b/web/src/routes/maintenance/MaintenanceRestoreFlow.svelte @@ -1,6 +1,9 @@ -{#if stage === 0} - stage++} {end} /> -{:else} - stage--} {end} {expectedVersion} /> +{#if stage === 'overview'} + (stage = 'yucca')} flowToDatabase={() => (stage = 'detect-install')} {end} /> +{:else if stage === 'yucca'} + (stage = 'overview')} onFinish={() => (stage = 'auto-select-backup')} /> +{:else if stage === 'detect-install'} + (stage = 'select-backup')} previous={() => (stage = 'overview')} /> +{:else if stage === 'select-backup'} + (stage = 'detect-install')} {end} {expectedVersion} /> +{:else if stage === 'auto-select-backup'} + (stage = 'select-backup')} {end} {expectedVersion} /> {/if} diff --git a/web/src/routes/maintenance/RestoreFlowAutoSelectBackup.svelte b/web/src/routes/maintenance/RestoreFlowAutoSelectBackup.svelte new file mode 100644 index 0000000000..ea5eb31acb --- /dev/null +++ b/web/src/routes/maintenance/RestoreFlowAutoSelectBackup.svelte @@ -0,0 +1,62 @@ + + +{$t('maintenance_restore_from_backup')} + +{#if backups === undefined} + + + {$t('maintenance_restore_loading_backups')} + +{:else if latest === undefined} + + + + + +{:else} + {$t('maintenance_restore_latest_backup_description')} + + + + + + + +{/if} diff --git a/web/src/routes/maintenance/RestoreFlowDetectInstall.svelte b/web/src/routes/maintenance/RestoreFlowDetectInstall.svelte index ef3e4c3a53..9a12c5a8ab 100644 --- a/web/src/routes/maintenance/RestoreFlowDetectInstall.svelte +++ b/web/src/routes/maintenance/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/routes/maintenance/RestoreFlowIntro.svelte b/web/src/routes/maintenance/RestoreFlowIntro.svelte new file mode 100644 index 0000000000..b33f7cf957 --- /dev/null +++ b/web/src/routes/maintenance/RestoreFlowIntro.svelte @@ -0,0 +1,20 @@ + + +Where would you like to restore from? + + + + +