From 279481ad544d0919113ffdd392863b4d7c67c08e Mon Sep 17 00:00:00 2001 From: Jason Rasmussen Date: Mon, 6 Nov 2023 09:04:39 -0500 Subject: [PATCH] feat(server): make is favorite optional on asset upload (#4865) * feat(server): make isFavorite optional * chore: open api * chore: e2e --- cli/src/api/open-api/api.ts | 32 ++++++++---------- mobile/openapi/doc/AssetApi.md | Bin 66635 -> 66646 bytes mobile/openapi/doc/ImportAssetDto.md | Bin 986 -> 997 bytes mobile/openapi/lib/api/asset_api.dart | Bin 58774 -> 58766 bytes .../openapi/lib/model/import_asset_dto.dart | Bin 9437 -> 9875 bytes mobile/openapi/test/asset_api_test.dart | Bin 5896 -> 5896 bytes server/immich-openapi-specs.json | 6 ++-- .../api-v1/asset/dto/create-asset.dto.ts | 3 +- server/test/e2e/asset.e2e-spec.ts | 1 - web/src/api/open-api/api.ts | 32 ++++++++---------- 10 files changed, 34 insertions(+), 40 deletions(-) diff --git a/cli/src/api/open-api/api.ts b/cli/src/api/open-api/api.ts index 9f4d765f2d..5a2445846a 100644 --- a/cli/src/api/open-api/api.ts +++ b/cli/src/api/open-api/api.ts @@ -1855,7 +1855,7 @@ export interface ImportAssetDto { * @type {boolean} * @memberof ImportAssetDto */ - 'isFavorite': boolean; + 'isFavorite'?: boolean; /** * * @type {boolean} @@ -7868,11 +7868,11 @@ export const AssetApiAxiosParamCreator = function (configuration?: Configuration * @param {string} deviceId * @param {string} fileCreatedAt * @param {string} fileModifiedAt - * @param {boolean} isFavorite * @param {string} [key] * @param {string} [duration] * @param {boolean} [isArchived] * @param {boolean} [isExternal] + * @param {boolean} [isFavorite] * @param {boolean} [isOffline] * @param {boolean} [isReadOnly] * @param {boolean} [isVisible] @@ -7882,7 +7882,7 @@ export const AssetApiAxiosParamCreator = function (configuration?: Configuration * @param {*} [options] Override http request option. * @throws {RequiredError} */ - uploadFile: async (assetData: File, deviceAssetId: string, deviceId: string, fileCreatedAt: string, fileModifiedAt: string, isFavorite: boolean, key?: string, duration?: string, isArchived?: boolean, isExternal?: boolean, isOffline?: boolean, isReadOnly?: boolean, isVisible?: boolean, libraryId?: string, livePhotoData?: File, sidecarData?: File, options: AxiosRequestConfig = {}): Promise => { + uploadFile: async (assetData: File, deviceAssetId: string, deviceId: string, fileCreatedAt: string, fileModifiedAt: string, key?: string, duration?: string, isArchived?: boolean, isExternal?: boolean, isFavorite?: boolean, isOffline?: boolean, isReadOnly?: boolean, isVisible?: boolean, libraryId?: string, livePhotoData?: File, sidecarData?: File, options: AxiosRequestConfig = {}): Promise => { // verify required parameter 'assetData' is not null or undefined assertParamExists('uploadFile', 'assetData', assetData) // verify required parameter 'deviceAssetId' is not null or undefined @@ -7893,8 +7893,6 @@ export const AssetApiAxiosParamCreator = function (configuration?: Configuration assertParamExists('uploadFile', 'fileCreatedAt', fileCreatedAt) // verify required parameter 'fileModifiedAt' is not null or undefined assertParamExists('uploadFile', 'fileModifiedAt', fileModifiedAt) - // verify required parameter 'isFavorite' is not null or undefined - assertParamExists('uploadFile', 'isFavorite', isFavorite) const localVarPath = `/asset/upload`; // use dummy base URL string because the URL constructor only accepts absolute URLs. const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL); @@ -8335,11 +8333,11 @@ export const AssetApiFp = function(configuration?: Configuration) { * @param {string} deviceId * @param {string} fileCreatedAt * @param {string} fileModifiedAt - * @param {boolean} isFavorite * @param {string} [key] * @param {string} [duration] * @param {boolean} [isArchived] * @param {boolean} [isExternal] + * @param {boolean} [isFavorite] * @param {boolean} [isOffline] * @param {boolean} [isReadOnly] * @param {boolean} [isVisible] @@ -8349,8 +8347,8 @@ export const AssetApiFp = function(configuration?: Configuration) { * @param {*} [options] Override http request option. * @throws {RequiredError} */ - async uploadFile(assetData: File, deviceAssetId: string, deviceId: string, fileCreatedAt: string, fileModifiedAt: string, isFavorite: boolean, key?: string, duration?: string, isArchived?: boolean, isExternal?: boolean, isOffline?: boolean, isReadOnly?: boolean, isVisible?: boolean, libraryId?: string, livePhotoData?: File, sidecarData?: File, options?: AxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise> { - const localVarAxiosArgs = await localVarAxiosParamCreator.uploadFile(assetData, deviceAssetId, deviceId, fileCreatedAt, fileModifiedAt, isFavorite, key, duration, isArchived, isExternal, isOffline, isReadOnly, isVisible, libraryId, livePhotoData, sidecarData, options); + async uploadFile(assetData: File, deviceAssetId: string, deviceId: string, fileCreatedAt: string, fileModifiedAt: string, key?: string, duration?: string, isArchived?: boolean, isExternal?: boolean, isFavorite?: boolean, isOffline?: boolean, isReadOnly?: boolean, isVisible?: boolean, libraryId?: string, livePhotoData?: File, sidecarData?: File, options?: AxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise> { + const localVarAxiosArgs = await localVarAxiosParamCreator.uploadFile(assetData, deviceAssetId, deviceId, fileCreatedAt, fileModifiedAt, key, duration, isArchived, isExternal, isFavorite, isOffline, isReadOnly, isVisible, libraryId, livePhotoData, sidecarData, options); return createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration); }, } @@ -8626,7 +8624,7 @@ export const AssetApiFactory = function (configuration?: Configuration, basePath * @throws {RequiredError} */ uploadFile(requestParameters: AssetApiUploadFileRequest, options?: AxiosRequestConfig): AxiosPromise { - return localVarFp.uploadFile(requestParameters.assetData, requestParameters.deviceAssetId, requestParameters.deviceId, requestParameters.fileCreatedAt, requestParameters.fileModifiedAt, requestParameters.isFavorite, requestParameters.key, requestParameters.duration, requestParameters.isArchived, requestParameters.isExternal, requestParameters.isOffline, requestParameters.isReadOnly, requestParameters.isVisible, requestParameters.libraryId, requestParameters.livePhotoData, requestParameters.sidecarData, options).then((request) => request(axios, basePath)); + return localVarFp.uploadFile(requestParameters.assetData, requestParameters.deviceAssetId, requestParameters.deviceId, requestParameters.fileCreatedAt, requestParameters.fileModifiedAt, requestParameters.key, requestParameters.duration, requestParameters.isArchived, requestParameters.isExternal, requestParameters.isFavorite, requestParameters.isOffline, requestParameters.isReadOnly, requestParameters.isVisible, requestParameters.libraryId, requestParameters.livePhotoData, requestParameters.sidecarData, options).then((request) => request(axios, basePath)); }, }; }; @@ -9274,13 +9272,6 @@ export interface AssetApiUploadFileRequest { */ readonly fileModifiedAt: string - /** - * - * @type {boolean} - * @memberof AssetApiUploadFile - */ - readonly isFavorite: boolean - /** * * @type {string} @@ -9309,6 +9300,13 @@ export interface AssetApiUploadFileRequest { */ readonly isExternal?: boolean + /** + * + * @type {boolean} + * @memberof AssetApiUploadFile + */ + readonly isFavorite?: boolean + /** * * @type {boolean} @@ -9681,7 +9679,7 @@ export class AssetApi extends BaseAPI { * @memberof AssetApi */ public uploadFile(requestParameters: AssetApiUploadFileRequest, options?: AxiosRequestConfig) { - return AssetApiFp(this.configuration).uploadFile(requestParameters.assetData, requestParameters.deviceAssetId, requestParameters.deviceId, requestParameters.fileCreatedAt, requestParameters.fileModifiedAt, requestParameters.isFavorite, requestParameters.key, requestParameters.duration, requestParameters.isArchived, requestParameters.isExternal, requestParameters.isOffline, requestParameters.isReadOnly, requestParameters.isVisible, requestParameters.libraryId, requestParameters.livePhotoData, requestParameters.sidecarData, options).then((request) => request(this.axios, this.basePath)); + return AssetApiFp(this.configuration).uploadFile(requestParameters.assetData, requestParameters.deviceAssetId, requestParameters.deviceId, requestParameters.fileCreatedAt, requestParameters.fileModifiedAt, requestParameters.key, requestParameters.duration, requestParameters.isArchived, requestParameters.isExternal, requestParameters.isFavorite, requestParameters.isOffline, requestParameters.isReadOnly, requestParameters.isVisible, requestParameters.libraryId, requestParameters.livePhotoData, requestParameters.sidecarData, options).then((request) => request(this.axios, this.basePath)); } } diff --git a/mobile/openapi/doc/AssetApi.md b/mobile/openapi/doc/AssetApi.md index cf50f659df667ea15bf63a2e70f7fbb58bd386e8..e072c3ded9cbf11e5655f66d4080f9d4c0ed53a0 100644 GIT binary patch delta 85 zcmX@z!E&vGWkcGx$wl8ZIouM<@{2M{QYWwd=e0Q~T8U*d^KWIw$zFdJOtuYI+5GCy hBt{fl^UCV|cVOx=tCGUWvx delta 12 TcmaFLev5sB7t`iYrU{GyA!Gz) diff --git a/mobile/openapi/lib/api/asset_api.dart b/mobile/openapi/lib/api/asset_api.dart index b0e9c822d2f686239fc81c3993ac0966618d66c0..4b74d29333412dbb410d8ac6bad1e67e021eeda3 100644 GIT binary patch delta 92 zcmbPsnz`>Z^9Jn;lRwDwPkwW+V)DFB#m)CF#4}FzyW~4rQ$uL;>`P)i$g-2~T{t^A kWr6HuzXvriMU!V=>X^LYVc}%mM}dn0CjLKdH?_b delta 131 zcmeA>%{=Wi^9Jn;lQ$%BOrF=tF?nH?%H;L;>L>f(KRbEB#Yy~0`T02tnZ<62W%)&! vC8?7QF8NOudDt;Ipu~Q2#ASbObd8(+@24^1(DjoG$sq1W!JEq-NiYKd+%P-L diff --git a/mobile/openapi/lib/model/import_asset_dto.dart b/mobile/openapi/lib/model/import_asset_dto.dart index 66ee3faee2a7bd3e9d6f3235bd29ae1c1a325a4d..7ba26da9d7758607b20fdd6aa4f0b5e3a37b8913 100644 GIT binary patch delta 115 zcmccXIoWqZ1k>h3rf}BHZfvQHoAyC06bD?jfTY~!3h}F~oBd?V+1YBX IxoWw%00QwQZ2$lO delta 85 zcmV-b0IL6!P2EYbSON%gWpQ(JZqR&??|QIE;rc?BoCi5&s}R@Mk+ delta 31 mcmeCs>(JZqR+K*}KR-tyv)C=MEWaqTBz5v@QLo8vVut|6;S8hz diff --git a/server/immich-openapi-specs.json b/server/immich-openapi-specs.json index 75a57043f0..1fb05fbcf5 100644 --- a/server/immich-openapi-specs.json +++ b/server/immich-openapi-specs.json @@ -6655,8 +6655,7 @@ "deviceAssetId", "deviceId", "fileCreatedAt", - "fileModifiedAt", - "isFavorite" + "fileModifiedAt" ], "type": "object" }, @@ -7143,8 +7142,7 @@ "deviceAssetId", "deviceId", "fileCreatedAt", - "fileModifiedAt", - "isFavorite" + "fileModifiedAt" ], "type": "object" }, diff --git a/server/src/immich/api-v1/asset/dto/create-asset.dto.ts b/server/src/immich/api-v1/asset/dto/create-asset.dto.ts index de1f7f1bb5..0338fe792f 100644 --- a/server/src/immich/api-v1/asset/dto/create-asset.dto.ts +++ b/server/src/immich/api-v1/asset/dto/create-asset.dto.ts @@ -22,9 +22,10 @@ export class CreateAssetBase { @Type(() => Date) fileModifiedAt!: Date; + @Optional() @IsBoolean() @Transform(toBoolean) - isFavorite!: boolean; + isFavorite?: boolean; @Optional() @IsBoolean() diff --git a/server/test/e2e/asset.e2e-spec.ts b/server/test/e2e/asset.e2e-spec.ts index b9b10e1044..a6f8f48e75 100644 --- a/server/test/e2e/asset.e2e-spec.ts +++ b/server/test/e2e/asset.e2e-spec.ts @@ -146,7 +146,6 @@ describe(`${AssetController.name} (e2e)`, () => { { should: 'require `deviceId`', dto: { ...makeUploadDto({ omit: 'deviceId' }) } }, { should: 'require `fileCreatedAt`', dto: { ...makeUploadDto({ omit: 'fileCreatedAt' }) } }, { should: 'require `fileModifiedAt`', dto: { ...makeUploadDto({ omit: 'fileModifiedAt' }) } }, - { should: 'require `isFavorite`', dto: { ...makeUploadDto({ omit: 'isFavorite' }) } }, { should: 'require `duration`', dto: { ...makeUploadDto({ omit: 'duration' }) } }, { should: 'throw if `isFavorite` is not a boolean', dto: { ...makeUploadDto(), isFavorite: 'not-a-boolean' } }, { should: 'throw if `isVisible` is not a boolean', dto: { ...makeUploadDto(), isVisible: 'not-a-boolean' } }, diff --git a/web/src/api/open-api/api.ts b/web/src/api/open-api/api.ts index 9f4d765f2d..5a2445846a 100644 --- a/web/src/api/open-api/api.ts +++ b/web/src/api/open-api/api.ts @@ -1855,7 +1855,7 @@ export interface ImportAssetDto { * @type {boolean} * @memberof ImportAssetDto */ - 'isFavorite': boolean; + 'isFavorite'?: boolean; /** * * @type {boolean} @@ -7868,11 +7868,11 @@ export const AssetApiAxiosParamCreator = function (configuration?: Configuration * @param {string} deviceId * @param {string} fileCreatedAt * @param {string} fileModifiedAt - * @param {boolean} isFavorite * @param {string} [key] * @param {string} [duration] * @param {boolean} [isArchived] * @param {boolean} [isExternal] + * @param {boolean} [isFavorite] * @param {boolean} [isOffline] * @param {boolean} [isReadOnly] * @param {boolean} [isVisible] @@ -7882,7 +7882,7 @@ export const AssetApiAxiosParamCreator = function (configuration?: Configuration * @param {*} [options] Override http request option. * @throws {RequiredError} */ - uploadFile: async (assetData: File, deviceAssetId: string, deviceId: string, fileCreatedAt: string, fileModifiedAt: string, isFavorite: boolean, key?: string, duration?: string, isArchived?: boolean, isExternal?: boolean, isOffline?: boolean, isReadOnly?: boolean, isVisible?: boolean, libraryId?: string, livePhotoData?: File, sidecarData?: File, options: AxiosRequestConfig = {}): Promise => { + uploadFile: async (assetData: File, deviceAssetId: string, deviceId: string, fileCreatedAt: string, fileModifiedAt: string, key?: string, duration?: string, isArchived?: boolean, isExternal?: boolean, isFavorite?: boolean, isOffline?: boolean, isReadOnly?: boolean, isVisible?: boolean, libraryId?: string, livePhotoData?: File, sidecarData?: File, options: AxiosRequestConfig = {}): Promise => { // verify required parameter 'assetData' is not null or undefined assertParamExists('uploadFile', 'assetData', assetData) // verify required parameter 'deviceAssetId' is not null or undefined @@ -7893,8 +7893,6 @@ export const AssetApiAxiosParamCreator = function (configuration?: Configuration assertParamExists('uploadFile', 'fileCreatedAt', fileCreatedAt) // verify required parameter 'fileModifiedAt' is not null or undefined assertParamExists('uploadFile', 'fileModifiedAt', fileModifiedAt) - // verify required parameter 'isFavorite' is not null or undefined - assertParamExists('uploadFile', 'isFavorite', isFavorite) const localVarPath = `/asset/upload`; // use dummy base URL string because the URL constructor only accepts absolute URLs. const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL); @@ -8335,11 +8333,11 @@ export const AssetApiFp = function(configuration?: Configuration) { * @param {string} deviceId * @param {string} fileCreatedAt * @param {string} fileModifiedAt - * @param {boolean} isFavorite * @param {string} [key] * @param {string} [duration] * @param {boolean} [isArchived] * @param {boolean} [isExternal] + * @param {boolean} [isFavorite] * @param {boolean} [isOffline] * @param {boolean} [isReadOnly] * @param {boolean} [isVisible] @@ -8349,8 +8347,8 @@ export const AssetApiFp = function(configuration?: Configuration) { * @param {*} [options] Override http request option. * @throws {RequiredError} */ - async uploadFile(assetData: File, deviceAssetId: string, deviceId: string, fileCreatedAt: string, fileModifiedAt: string, isFavorite: boolean, key?: string, duration?: string, isArchived?: boolean, isExternal?: boolean, isOffline?: boolean, isReadOnly?: boolean, isVisible?: boolean, libraryId?: string, livePhotoData?: File, sidecarData?: File, options?: AxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise> { - const localVarAxiosArgs = await localVarAxiosParamCreator.uploadFile(assetData, deviceAssetId, deviceId, fileCreatedAt, fileModifiedAt, isFavorite, key, duration, isArchived, isExternal, isOffline, isReadOnly, isVisible, libraryId, livePhotoData, sidecarData, options); + async uploadFile(assetData: File, deviceAssetId: string, deviceId: string, fileCreatedAt: string, fileModifiedAt: string, key?: string, duration?: string, isArchived?: boolean, isExternal?: boolean, isFavorite?: boolean, isOffline?: boolean, isReadOnly?: boolean, isVisible?: boolean, libraryId?: string, livePhotoData?: File, sidecarData?: File, options?: AxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise> { + const localVarAxiosArgs = await localVarAxiosParamCreator.uploadFile(assetData, deviceAssetId, deviceId, fileCreatedAt, fileModifiedAt, key, duration, isArchived, isExternal, isFavorite, isOffline, isReadOnly, isVisible, libraryId, livePhotoData, sidecarData, options); return createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration); }, } @@ -8626,7 +8624,7 @@ export const AssetApiFactory = function (configuration?: Configuration, basePath * @throws {RequiredError} */ uploadFile(requestParameters: AssetApiUploadFileRequest, options?: AxiosRequestConfig): AxiosPromise { - return localVarFp.uploadFile(requestParameters.assetData, requestParameters.deviceAssetId, requestParameters.deviceId, requestParameters.fileCreatedAt, requestParameters.fileModifiedAt, requestParameters.isFavorite, requestParameters.key, requestParameters.duration, requestParameters.isArchived, requestParameters.isExternal, requestParameters.isOffline, requestParameters.isReadOnly, requestParameters.isVisible, requestParameters.libraryId, requestParameters.livePhotoData, requestParameters.sidecarData, options).then((request) => request(axios, basePath)); + return localVarFp.uploadFile(requestParameters.assetData, requestParameters.deviceAssetId, requestParameters.deviceId, requestParameters.fileCreatedAt, requestParameters.fileModifiedAt, requestParameters.key, requestParameters.duration, requestParameters.isArchived, requestParameters.isExternal, requestParameters.isFavorite, requestParameters.isOffline, requestParameters.isReadOnly, requestParameters.isVisible, requestParameters.libraryId, requestParameters.livePhotoData, requestParameters.sidecarData, options).then((request) => request(axios, basePath)); }, }; }; @@ -9274,13 +9272,6 @@ export interface AssetApiUploadFileRequest { */ readonly fileModifiedAt: string - /** - * - * @type {boolean} - * @memberof AssetApiUploadFile - */ - readonly isFavorite: boolean - /** * * @type {string} @@ -9309,6 +9300,13 @@ export interface AssetApiUploadFileRequest { */ readonly isExternal?: boolean + /** + * + * @type {boolean} + * @memberof AssetApiUploadFile + */ + readonly isFavorite?: boolean + /** * * @type {boolean} @@ -9681,7 +9679,7 @@ export class AssetApi extends BaseAPI { * @memberof AssetApi */ public uploadFile(requestParameters: AssetApiUploadFileRequest, options?: AxiosRequestConfig) { - return AssetApiFp(this.configuration).uploadFile(requestParameters.assetData, requestParameters.deviceAssetId, requestParameters.deviceId, requestParameters.fileCreatedAt, requestParameters.fileModifiedAt, requestParameters.isFavorite, requestParameters.key, requestParameters.duration, requestParameters.isArchived, requestParameters.isExternal, requestParameters.isOffline, requestParameters.isReadOnly, requestParameters.isVisible, requestParameters.libraryId, requestParameters.livePhotoData, requestParameters.sidecarData, options).then((request) => request(this.axios, this.basePath)); + return AssetApiFp(this.configuration).uploadFile(requestParameters.assetData, requestParameters.deviceAssetId, requestParameters.deviceId, requestParameters.fileCreatedAt, requestParameters.fileModifiedAt, requestParameters.key, requestParameters.duration, requestParameters.isArchived, requestParameters.isExternal, requestParameters.isFavorite, requestParameters.isOffline, requestParameters.isReadOnly, requestParameters.isVisible, requestParameters.libraryId, requestParameters.livePhotoData, requestParameters.sidecarData, options).then((request) => request(this.axios, this.basePath)); } }