mirror of
https://github.com/immich-app/immich
synced 2025-11-14 17:36:12 +00:00
feat: endpoint versioning (#23858)
This commit is contained in:
parent
e0535e20e6
commit
4a6c50cd81
53 changed files with 4247 additions and 705 deletions
12
mobile/openapi/lib/api/assets_api.dart
generated
12
mobile/openapi/lib/api/assets_api.dart
generated
|
|
@ -352,7 +352,7 @@ class AssetsApi {
|
||||||
|
|
||||||
/// Retrieve assets by device ID
|
/// Retrieve assets by device ID
|
||||||
///
|
///
|
||||||
/// This property was deprecated in v2.0.0. Get all asset of a device that are in the database, ID only.
|
/// Get all asset of a device that are in the database, ID only.
|
||||||
///
|
///
|
||||||
/// Note: This method returns the HTTP [Response].
|
/// Note: This method returns the HTTP [Response].
|
||||||
///
|
///
|
||||||
|
|
@ -387,7 +387,7 @@ class AssetsApi {
|
||||||
|
|
||||||
/// Retrieve assets by device ID
|
/// Retrieve assets by device ID
|
||||||
///
|
///
|
||||||
/// This property was deprecated in v2.0.0. Get all asset of a device that are in the database, ID only.
|
/// Get all asset of a device that are in the database, ID only.
|
||||||
///
|
///
|
||||||
/// Parameters:
|
/// Parameters:
|
||||||
///
|
///
|
||||||
|
|
@ -740,7 +740,7 @@ class AssetsApi {
|
||||||
|
|
||||||
/// Get random assets
|
/// Get random assets
|
||||||
///
|
///
|
||||||
/// This property was deprecated in v1.116.0. Retrieve a specified number of random assets for the authenticated user.
|
/// Retrieve a specified number of random assets for the authenticated user.
|
||||||
///
|
///
|
||||||
/// Note: This method returns the HTTP [Response].
|
/// Note: This method returns the HTTP [Response].
|
||||||
///
|
///
|
||||||
|
|
@ -778,7 +778,7 @@ class AssetsApi {
|
||||||
|
|
||||||
/// Get random assets
|
/// Get random assets
|
||||||
///
|
///
|
||||||
/// This property was deprecated in v1.116.0. Retrieve a specified number of random assets for the authenticated user.
|
/// Retrieve a specified number of random assets for the authenticated user.
|
||||||
///
|
///
|
||||||
/// Parameters:
|
/// Parameters:
|
||||||
///
|
///
|
||||||
|
|
@ -875,7 +875,7 @@ class AssetsApi {
|
||||||
|
|
||||||
/// Replace asset
|
/// Replace asset
|
||||||
///
|
///
|
||||||
/// This property was deprecated in v1.142.0. Replace the asset with new file, without changing its id.
|
/// Replace the asset with new file, without changing its id.
|
||||||
///
|
///
|
||||||
/// Note: This method returns the HTTP [Response].
|
/// Note: This method returns the HTTP [Response].
|
||||||
///
|
///
|
||||||
|
|
@ -969,7 +969,7 @@ class AssetsApi {
|
||||||
|
|
||||||
/// Replace asset
|
/// Replace asset
|
||||||
///
|
///
|
||||||
/// This property was deprecated in v1.142.0. Replace the asset with new file, without changing its id.
|
/// Replace the asset with new file, without changing its id.
|
||||||
///
|
///
|
||||||
/// Parameters:
|
/// Parameters:
|
||||||
///
|
///
|
||||||
|
|
|
||||||
24
mobile/openapi/lib/api/deprecated_api.dart
generated
24
mobile/openapi/lib/api/deprecated_api.dart
generated
|
|
@ -18,7 +18,7 @@ class DeprecatedApi {
|
||||||
|
|
||||||
/// Create a partner
|
/// Create a partner
|
||||||
///
|
///
|
||||||
/// This property was deprecated in v1.141.0. Create a new partner to share assets with.
|
/// Create a new partner to share assets with.
|
||||||
///
|
///
|
||||||
/// Note: This method returns the HTTP [Response].
|
/// Note: This method returns the HTTP [Response].
|
||||||
///
|
///
|
||||||
|
|
@ -53,7 +53,7 @@ class DeprecatedApi {
|
||||||
|
|
||||||
/// Create a partner
|
/// Create a partner
|
||||||
///
|
///
|
||||||
/// This property was deprecated in v1.141.0. Create a new partner to share assets with.
|
/// Create a new partner to share assets with.
|
||||||
///
|
///
|
||||||
/// Parameters:
|
/// Parameters:
|
||||||
///
|
///
|
||||||
|
|
@ -75,7 +75,7 @@ class DeprecatedApi {
|
||||||
|
|
||||||
/// Retrieve assets by device ID
|
/// Retrieve assets by device ID
|
||||||
///
|
///
|
||||||
/// This property was deprecated in v2.0.0. Get all asset of a device that are in the database, ID only.
|
/// Get all asset of a device that are in the database, ID only.
|
||||||
///
|
///
|
||||||
/// Note: This method returns the HTTP [Response].
|
/// Note: This method returns the HTTP [Response].
|
||||||
///
|
///
|
||||||
|
|
@ -110,7 +110,7 @@ class DeprecatedApi {
|
||||||
|
|
||||||
/// Retrieve assets by device ID
|
/// Retrieve assets by device ID
|
||||||
///
|
///
|
||||||
/// This property was deprecated in v2.0.0. Get all asset of a device that are in the database, ID only.
|
/// Get all asset of a device that are in the database, ID only.
|
||||||
///
|
///
|
||||||
/// Parameters:
|
/// Parameters:
|
||||||
///
|
///
|
||||||
|
|
@ -135,7 +135,7 @@ class DeprecatedApi {
|
||||||
|
|
||||||
/// Get delta sync for user
|
/// Get delta sync for user
|
||||||
///
|
///
|
||||||
/// This property was deprecated in v2.0.0. Retrieve changed assets since the last sync for the authenticated user.
|
/// Retrieve changed assets since the last sync for the authenticated user.
|
||||||
///
|
///
|
||||||
/// Note: This method returns the HTTP [Response].
|
/// Note: This method returns the HTTP [Response].
|
||||||
///
|
///
|
||||||
|
|
@ -169,7 +169,7 @@ class DeprecatedApi {
|
||||||
|
|
||||||
/// Get delta sync for user
|
/// Get delta sync for user
|
||||||
///
|
///
|
||||||
/// This property was deprecated in v2.0.0. Retrieve changed assets since the last sync for the authenticated user.
|
/// Retrieve changed assets since the last sync for the authenticated user.
|
||||||
///
|
///
|
||||||
/// Parameters:
|
/// Parameters:
|
||||||
///
|
///
|
||||||
|
|
@ -191,7 +191,7 @@ class DeprecatedApi {
|
||||||
|
|
||||||
/// Get full sync for user
|
/// Get full sync for user
|
||||||
///
|
///
|
||||||
/// This property was deprecated in v2.0.0. Retrieve all assets for a full synchronization for the authenticated user.
|
/// Retrieve all assets for a full synchronization for the authenticated user.
|
||||||
///
|
///
|
||||||
/// Note: This method returns the HTTP [Response].
|
/// Note: This method returns the HTTP [Response].
|
||||||
///
|
///
|
||||||
|
|
@ -225,7 +225,7 @@ class DeprecatedApi {
|
||||||
|
|
||||||
/// Get full sync for user
|
/// Get full sync for user
|
||||||
///
|
///
|
||||||
/// This property was deprecated in v2.0.0. Retrieve all assets for a full synchronization for the authenticated user.
|
/// Retrieve all assets for a full synchronization for the authenticated user.
|
||||||
///
|
///
|
||||||
/// Parameters:
|
/// Parameters:
|
||||||
///
|
///
|
||||||
|
|
@ -250,7 +250,7 @@ class DeprecatedApi {
|
||||||
|
|
||||||
/// Get random assets
|
/// Get random assets
|
||||||
///
|
///
|
||||||
/// This property was deprecated in v1.116.0. Retrieve a specified number of random assets for the authenticated user.
|
/// Retrieve a specified number of random assets for the authenticated user.
|
||||||
///
|
///
|
||||||
/// Note: This method returns the HTTP [Response].
|
/// Note: This method returns the HTTP [Response].
|
||||||
///
|
///
|
||||||
|
|
@ -288,7 +288,7 @@ class DeprecatedApi {
|
||||||
|
|
||||||
/// Get random assets
|
/// Get random assets
|
||||||
///
|
///
|
||||||
/// This property was deprecated in v1.116.0. Retrieve a specified number of random assets for the authenticated user.
|
/// Retrieve a specified number of random assets for the authenticated user.
|
||||||
///
|
///
|
||||||
/// Parameters:
|
/// Parameters:
|
||||||
///
|
///
|
||||||
|
|
@ -313,7 +313,7 @@ class DeprecatedApi {
|
||||||
|
|
||||||
/// Replace asset
|
/// Replace asset
|
||||||
///
|
///
|
||||||
/// This property was deprecated in v1.142.0. Replace the asset with new file, without changing its id.
|
/// Replace the asset with new file, without changing its id.
|
||||||
///
|
///
|
||||||
/// Note: This method returns the HTTP [Response].
|
/// Note: This method returns the HTTP [Response].
|
||||||
///
|
///
|
||||||
|
|
@ -407,7 +407,7 @@ class DeprecatedApi {
|
||||||
|
|
||||||
/// Replace asset
|
/// Replace asset
|
||||||
///
|
///
|
||||||
/// This property was deprecated in v1.142.0. Replace the asset with new file, without changing its id.
|
/// Replace the asset with new file, without changing its id.
|
||||||
///
|
///
|
||||||
/// Parameters:
|
/// Parameters:
|
||||||
///
|
///
|
||||||
|
|
|
||||||
4
mobile/openapi/lib/api/partners_api.dart
generated
4
mobile/openapi/lib/api/partners_api.dart
generated
|
|
@ -74,7 +74,7 @@ class PartnersApi {
|
||||||
|
|
||||||
/// Create a partner
|
/// Create a partner
|
||||||
///
|
///
|
||||||
/// This property was deprecated in v1.141.0. Create a new partner to share assets with.
|
/// Create a new partner to share assets with.
|
||||||
///
|
///
|
||||||
/// Note: This method returns the HTTP [Response].
|
/// Note: This method returns the HTTP [Response].
|
||||||
///
|
///
|
||||||
|
|
@ -109,7 +109,7 @@ class PartnersApi {
|
||||||
|
|
||||||
/// Create a partner
|
/// Create a partner
|
||||||
///
|
///
|
||||||
/// This property was deprecated in v1.141.0. Create a new partner to share assets with.
|
/// Create a new partner to share assets with.
|
||||||
///
|
///
|
||||||
/// Parameters:
|
/// Parameters:
|
||||||
///
|
///
|
||||||
|
|
|
||||||
2
mobile/openapi/lib/api/search_api.dart
generated
2
mobile/openapi/lib/api/search_api.dart
generated
|
|
@ -131,7 +131,6 @@ class SearchApi {
|
||||||
/// * [String] country:
|
/// * [String] country:
|
||||||
///
|
///
|
||||||
/// * [bool] includeNull:
|
/// * [bool] includeNull:
|
||||||
/// This property was added in v111.0.0
|
|
||||||
///
|
///
|
||||||
/// * [String] lensModel:
|
/// * [String] lensModel:
|
||||||
///
|
///
|
||||||
|
|
@ -196,7 +195,6 @@ class SearchApi {
|
||||||
/// * [String] country:
|
/// * [String] country:
|
||||||
///
|
///
|
||||||
/// * [bool] includeNull:
|
/// * [bool] includeNull:
|
||||||
/// This property was added in v111.0.0
|
|
||||||
///
|
///
|
||||||
/// * [String] lensModel:
|
/// * [String] lensModel:
|
||||||
///
|
///
|
||||||
|
|
|
||||||
8
mobile/openapi/lib/api/sync_api.dart
generated
8
mobile/openapi/lib/api/sync_api.dart
generated
|
|
@ -66,7 +66,7 @@ class SyncApi {
|
||||||
|
|
||||||
/// Get delta sync for user
|
/// Get delta sync for user
|
||||||
///
|
///
|
||||||
/// This property was deprecated in v2.0.0. Retrieve changed assets since the last sync for the authenticated user.
|
/// Retrieve changed assets since the last sync for the authenticated user.
|
||||||
///
|
///
|
||||||
/// Note: This method returns the HTTP [Response].
|
/// Note: This method returns the HTTP [Response].
|
||||||
///
|
///
|
||||||
|
|
@ -100,7 +100,7 @@ class SyncApi {
|
||||||
|
|
||||||
/// Get delta sync for user
|
/// Get delta sync for user
|
||||||
///
|
///
|
||||||
/// This property was deprecated in v2.0.0. Retrieve changed assets since the last sync for the authenticated user.
|
/// Retrieve changed assets since the last sync for the authenticated user.
|
||||||
///
|
///
|
||||||
/// Parameters:
|
/// Parameters:
|
||||||
///
|
///
|
||||||
|
|
@ -122,7 +122,7 @@ class SyncApi {
|
||||||
|
|
||||||
/// Get full sync for user
|
/// Get full sync for user
|
||||||
///
|
///
|
||||||
/// This property was deprecated in v2.0.0. Retrieve all assets for a full synchronization for the authenticated user.
|
/// Retrieve all assets for a full synchronization for the authenticated user.
|
||||||
///
|
///
|
||||||
/// Note: This method returns the HTTP [Response].
|
/// Note: This method returns the HTTP [Response].
|
||||||
///
|
///
|
||||||
|
|
@ -156,7 +156,7 @@ class SyncApi {
|
||||||
|
|
||||||
/// Get full sync for user
|
/// Get full sync for user
|
||||||
///
|
///
|
||||||
/// This property was deprecated in v2.0.0. Retrieve all assets for a full synchronization for the authenticated user.
|
/// Retrieve all assets for a full synchronization for the authenticated user.
|
||||||
///
|
///
|
||||||
/// Parameters:
|
/// Parameters:
|
||||||
///
|
///
|
||||||
|
|
|
||||||
2
mobile/openapi/lib/model/asset_response_dto.dart
generated
2
mobile/openapi/lib/model/asset_response_dto.dart
generated
|
|
@ -87,7 +87,6 @@ class AssetResponseDto {
|
||||||
|
|
||||||
bool isTrashed;
|
bool isTrashed;
|
||||||
|
|
||||||
/// This property was deprecated in v1.106.0
|
|
||||||
String? libraryId;
|
String? libraryId;
|
||||||
|
|
||||||
String? livePhotoVideoId;
|
String? livePhotoVideoId;
|
||||||
|
|
@ -119,7 +118,6 @@ class AssetResponseDto {
|
||||||
|
|
||||||
List<PersonWithFacesResponseDto> people;
|
List<PersonWithFacesResponseDto> people;
|
||||||
|
|
||||||
/// This property was deprecated in v1.113.0
|
|
||||||
///
|
///
|
||||||
/// Please note: This property should have been non-nullable! Since the specification file
|
/// 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
|
/// does not include a default value (using the "default:" property), however, the generated
|
||||||
|
|
|
||||||
|
|
@ -19,7 +19,6 @@ class PeopleResponseDto {
|
||||||
required this.total,
|
required this.total,
|
||||||
});
|
});
|
||||||
|
|
||||||
/// This property was added in v1.110.0
|
|
||||||
///
|
///
|
||||||
/// Please note: This property should have been non-nullable! Since the specification file
|
/// 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
|
/// does not include a default value (using the "default:" property), however, the generated
|
||||||
|
|
|
||||||
|
|
@ -25,7 +25,6 @@ class PersonResponseDto {
|
||||||
|
|
||||||
DateTime? birthDate;
|
DateTime? birthDate;
|
||||||
|
|
||||||
/// This property was added in v1.126.0
|
|
||||||
///
|
///
|
||||||
/// Please note: This property should have been non-nullable! Since the specification file
|
/// 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
|
/// does not include a default value (using the "default:" property), however, the generated
|
||||||
|
|
@ -36,7 +35,6 @@ class PersonResponseDto {
|
||||||
|
|
||||||
String id;
|
String id;
|
||||||
|
|
||||||
/// This property was added in v1.126.0
|
|
||||||
///
|
///
|
||||||
/// Please note: This property should have been non-nullable! Since the specification file
|
/// 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
|
/// does not include a default value (using the "default:" property), however, the generated
|
||||||
|
|
@ -51,7 +49,6 @@ class PersonResponseDto {
|
||||||
|
|
||||||
String thumbnailPath;
|
String thumbnailPath;
|
||||||
|
|
||||||
/// This property was added in v1.107.0
|
|
||||||
///
|
///
|
||||||
/// Please note: This property should have been non-nullable! Since the specification file
|
/// 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
|
/// does not include a default value (using the "default:" property), however, the generated
|
||||||
|
|
|
||||||
|
|
@ -26,7 +26,6 @@ class PersonWithFacesResponseDto {
|
||||||
|
|
||||||
DateTime? birthDate;
|
DateTime? birthDate;
|
||||||
|
|
||||||
/// This property was added in v1.126.0
|
|
||||||
///
|
///
|
||||||
/// Please note: This property should have been non-nullable! Since the specification file
|
/// 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
|
/// does not include a default value (using the "default:" property), however, the generated
|
||||||
|
|
@ -39,7 +38,6 @@ class PersonWithFacesResponseDto {
|
||||||
|
|
||||||
String id;
|
String id;
|
||||||
|
|
||||||
/// This property was added in v1.126.0
|
|
||||||
///
|
///
|
||||||
/// Please note: This property should have been non-nullable! Since the specification file
|
/// 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
|
/// does not include a default value (using the "default:" property), however, the generated
|
||||||
|
|
@ -54,7 +52,6 @@ class PersonWithFacesResponseDto {
|
||||||
|
|
||||||
String thumbnailPath;
|
String thumbnailPath;
|
||||||
|
|
||||||
/// This property was added in v1.107.0
|
|
||||||
///
|
///
|
||||||
/// Please note: This property should have been non-nullable! Since the specification file
|
/// 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
|
/// does not include a default value (using the "default:" property), however, the generated
|
||||||
|
|
|
||||||
File diff suppressed because it is too large
Load diff
|
|
@ -302,16 +302,13 @@ export type AssetFaceWithoutPersonResponseDto = {
|
||||||
};
|
};
|
||||||
export type PersonWithFacesResponseDto = {
|
export type PersonWithFacesResponseDto = {
|
||||||
birthDate: string | null;
|
birthDate: string | null;
|
||||||
/** This property was added in v1.126.0 */
|
|
||||||
color?: string;
|
color?: string;
|
||||||
faces: AssetFaceWithoutPersonResponseDto[];
|
faces: AssetFaceWithoutPersonResponseDto[];
|
||||||
id: string;
|
id: string;
|
||||||
/** This property was added in v1.126.0 */
|
|
||||||
isFavorite?: boolean;
|
isFavorite?: boolean;
|
||||||
isHidden: boolean;
|
isHidden: boolean;
|
||||||
name: string;
|
name: string;
|
||||||
thumbnailPath: string;
|
thumbnailPath: string;
|
||||||
/** This property was added in v1.107.0 */
|
|
||||||
updatedAt?: string;
|
updatedAt?: string;
|
||||||
};
|
};
|
||||||
export type AssetStackResponseDto = {
|
export type AssetStackResponseDto = {
|
||||||
|
|
@ -348,7 +345,6 @@ export type AssetResponseDto = {
|
||||||
isFavorite: boolean;
|
isFavorite: boolean;
|
||||||
isOffline: boolean;
|
isOffline: boolean;
|
||||||
isTrashed: boolean;
|
isTrashed: boolean;
|
||||||
/** This property was deprecated in v1.106.0 */
|
|
||||||
libraryId?: string | null;
|
libraryId?: string | null;
|
||||||
livePhotoVideoId?: string | null;
|
livePhotoVideoId?: string | null;
|
||||||
/** The local date and time when the photo/video was taken, derived from EXIF metadata. This represents the photographer's local time regardless of timezone, stored as a timezone-agnostic timestamp. Used for timeline grouping by "local" days and months. */
|
/** The local date and time when the photo/video was taken, derived from EXIF metadata. This represents the photographer's local time regardless of timezone, stored as a timezone-agnostic timestamp. Used for timeline grouping by "local" days and months. */
|
||||||
|
|
@ -359,7 +355,6 @@ export type AssetResponseDto = {
|
||||||
owner?: UserResponseDto;
|
owner?: UserResponseDto;
|
||||||
ownerId: string;
|
ownerId: string;
|
||||||
people?: PersonWithFacesResponseDto[];
|
people?: PersonWithFacesResponseDto[];
|
||||||
/** This property was deprecated in v1.113.0 */
|
|
||||||
resized?: boolean;
|
resized?: boolean;
|
||||||
stack?: (AssetStackResponseDto) | null;
|
stack?: (AssetStackResponseDto) | null;
|
||||||
tags?: TagResponseDto[];
|
tags?: TagResponseDto[];
|
||||||
|
|
@ -669,15 +664,12 @@ export type DuplicateResponseDto = {
|
||||||
};
|
};
|
||||||
export type PersonResponseDto = {
|
export type PersonResponseDto = {
|
||||||
birthDate: string | null;
|
birthDate: string | null;
|
||||||
/** This property was added in v1.126.0 */
|
|
||||||
color?: string;
|
color?: string;
|
||||||
id: string;
|
id: string;
|
||||||
/** This property was added in v1.126.0 */
|
|
||||||
isFavorite?: boolean;
|
isFavorite?: boolean;
|
||||||
isHidden: boolean;
|
isHidden: boolean;
|
||||||
name: string;
|
name: string;
|
||||||
thumbnailPath: string;
|
thumbnailPath: string;
|
||||||
/** This property was added in v1.107.0 */
|
|
||||||
updatedAt?: string;
|
updatedAt?: string;
|
||||||
};
|
};
|
||||||
export type AssetFaceResponseDto = {
|
export type AssetFaceResponseDto = {
|
||||||
|
|
@ -874,7 +866,6 @@ export type PartnerUpdateDto = {
|
||||||
inTimeline: boolean;
|
inTimeline: boolean;
|
||||||
};
|
};
|
||||||
export type PeopleResponseDto = {
|
export type PeopleResponseDto = {
|
||||||
/** This property was added in v1.110.0 */
|
|
||||||
hasNextPage?: boolean;
|
hasNextPage?: boolean;
|
||||||
hidden: number;
|
hidden: number;
|
||||||
people: PersonResponseDto[];
|
people: PersonResponseDto[];
|
||||||
|
|
|
||||||
|
|
@ -22,7 +22,6 @@
|
||||||
"test:cov": "vitest --config test/vitest.config.mjs --coverage",
|
"test:cov": "vitest --config test/vitest.config.mjs --coverage",
|
||||||
"test:medium": "vitest --config test/vitest.config.medium.mjs",
|
"test:medium": "vitest --config test/vitest.config.medium.mjs",
|
||||||
"typeorm": "typeorm",
|
"typeorm": "typeorm",
|
||||||
"lifecycle": "node ./dist/utils/lifecycle.js",
|
|
||||||
"migrations:debug": "node ./dist/bin/migrations.js debug",
|
"migrations:debug": "node ./dist/bin/migrations.js debug",
|
||||||
"migrations:generate": "node ./dist/bin/migrations.js generate",
|
"migrations:generate": "node ./dist/bin/migrations.js generate",
|
||||||
"migrations:create": "node ./dist/bin/migrations.js create",
|
"migrations:create": "node ./dist/bin/migrations.js create",
|
||||||
|
|
|
||||||
|
|
@ -9,11 +9,6 @@ export const VECTORCHORD_VERSION_RANGE = '>=0.3 <0.6';
|
||||||
export const VECTORS_VERSION_RANGE = '>=0.2 <0.4';
|
export const VECTORS_VERSION_RANGE = '>=0.2 <0.4';
|
||||||
export const VECTOR_VERSION_RANGE = '>=0.5 <1';
|
export const VECTOR_VERSION_RANGE = '>=0.5 <1';
|
||||||
|
|
||||||
export const NEXT_RELEASE = 'NEXT_RELEASE';
|
|
||||||
export const LIFECYCLE_EXTENSION = 'x-immich-lifecycle';
|
|
||||||
export const DEPRECATED_IN_PREFIX = 'This property was deprecated in ';
|
|
||||||
export const ADDED_IN_PREFIX = 'This property was added in ';
|
|
||||||
|
|
||||||
export const JOBS_ASSET_PAGINATION_SIZE = 1000;
|
export const JOBS_ASSET_PAGINATION_SIZE = 1000;
|
||||||
export const JOBS_LIBRARY_PAGINATION_SIZE = 10_000;
|
export const JOBS_LIBRARY_PAGINATION_SIZE = 10_000;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
import { Body, Controller, Delete, Get, HttpCode, HttpStatus, Param, Post, Query, Res } from '@nestjs/common';
|
import { Body, Controller, Delete, Get, HttpCode, HttpStatus, Param, Post, Query, Res } from '@nestjs/common';
|
||||||
import { ApiOperation, ApiTags } from '@nestjs/swagger';
|
import { ApiTags } from '@nestjs/swagger';
|
||||||
import { Response } from 'express';
|
import { Response } from 'express';
|
||||||
|
import { Endpoint, HistoryBuilder } from 'src/decorators';
|
||||||
import {
|
import {
|
||||||
ActivityCreateDto,
|
ActivityCreateDto,
|
||||||
ActivityDto,
|
ActivityDto,
|
||||||
|
|
@ -21,10 +22,11 @@ export class ActivityController {
|
||||||
|
|
||||||
@Get()
|
@Get()
|
||||||
@Authenticated({ permission: Permission.ActivityRead })
|
@Authenticated({ permission: Permission.ActivityRead })
|
||||||
@ApiOperation({
|
@Endpoint({
|
||||||
summary: 'List all activities',
|
summary: 'List all activities',
|
||||||
description:
|
description:
|
||||||
'Returns a list of activities for the selected asset or album. The activities are returned in sorted order, with the oldest activities appearing first.',
|
'Returns a list of activities for the selected asset or album. The activities are returned in sorted order, with the oldest activities appearing first.',
|
||||||
|
history: new HistoryBuilder().added('v1').beta('v1').stable('v2'),
|
||||||
})
|
})
|
||||||
getActivities(@Auth() auth: AuthDto, @Query() dto: ActivitySearchDto): Promise<ActivityResponseDto[]> {
|
getActivities(@Auth() auth: AuthDto, @Query() dto: ActivitySearchDto): Promise<ActivityResponseDto[]> {
|
||||||
return this.service.getAll(auth, dto);
|
return this.service.getAll(auth, dto);
|
||||||
|
|
@ -32,9 +34,10 @@ export class ActivityController {
|
||||||
|
|
||||||
@Post()
|
@Post()
|
||||||
@Authenticated({ permission: Permission.ActivityCreate })
|
@Authenticated({ permission: Permission.ActivityCreate })
|
||||||
@ApiOperation({
|
@Endpoint({
|
||||||
summary: 'Create an activity',
|
summary: 'Create an activity',
|
||||||
description: 'Create a like or a comment for an album, or an asset in an album.',
|
description: 'Create a like or a comment for an album, or an asset in an album.',
|
||||||
|
history: new HistoryBuilder().added('v1').beta('v1').stable('v2'),
|
||||||
})
|
})
|
||||||
async createActivity(
|
async createActivity(
|
||||||
@Auth() auth: AuthDto,
|
@Auth() auth: AuthDto,
|
||||||
|
|
@ -50,9 +53,10 @@ export class ActivityController {
|
||||||
|
|
||||||
@Get('statistics')
|
@Get('statistics')
|
||||||
@Authenticated({ permission: Permission.ActivityStatistics })
|
@Authenticated({ permission: Permission.ActivityStatistics })
|
||||||
@ApiOperation({
|
@Endpoint({
|
||||||
summary: 'Retrieve activity statistics',
|
summary: 'Retrieve activity statistics',
|
||||||
description: 'Returns the number of likes and comments for a given album or asset in an album.',
|
description: 'Returns the number of likes and comments for a given album or asset in an album.',
|
||||||
|
history: new HistoryBuilder().added('v1').beta('v1').stable('v2'),
|
||||||
})
|
})
|
||||||
getActivityStatistics(@Auth() auth: AuthDto, @Query() dto: ActivityDto): Promise<ActivityStatisticsResponseDto> {
|
getActivityStatistics(@Auth() auth: AuthDto, @Query() dto: ActivityDto): Promise<ActivityStatisticsResponseDto> {
|
||||||
return this.service.getStatistics(auth, dto);
|
return this.service.getStatistics(auth, dto);
|
||||||
|
|
@ -61,9 +65,10 @@ export class ActivityController {
|
||||||
@Delete(':id')
|
@Delete(':id')
|
||||||
@Authenticated({ permission: Permission.ActivityDelete })
|
@Authenticated({ permission: Permission.ActivityDelete })
|
||||||
@HttpCode(HttpStatus.NO_CONTENT)
|
@HttpCode(HttpStatus.NO_CONTENT)
|
||||||
@ApiOperation({
|
@Endpoint({
|
||||||
summary: 'Delete an activity',
|
summary: 'Delete an activity',
|
||||||
description: 'Removes a like or comment from a given album or asset in an album.',
|
description: 'Removes a like or comment from a given album or asset in an album.',
|
||||||
|
history: new HistoryBuilder().added('v1').beta('v1').stable('v2'),
|
||||||
})
|
})
|
||||||
deleteActivity(@Auth() auth: AuthDto, @Param() { id }: UUIDParamDto): Promise<void> {
|
deleteActivity(@Auth() auth: AuthDto, @Param() { id }: UUIDParamDto): Promise<void> {
|
||||||
return this.service.delete(auth, id);
|
return this.service.delete(auth, id);
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,6 @@
|
||||||
import { Body, Controller, Delete, Get, HttpCode, HttpStatus, Param, Patch, Post, Put, Query } from '@nestjs/common';
|
import { Body, Controller, Delete, Get, HttpCode, HttpStatus, Param, Patch, Post, Put, Query } from '@nestjs/common';
|
||||||
import { ApiOperation, ApiTags } from '@nestjs/swagger';
|
import { ApiTags } from '@nestjs/swagger';
|
||||||
|
import { Endpoint, HistoryBuilder } from 'src/decorators';
|
||||||
import {
|
import {
|
||||||
AddUsersDto,
|
AddUsersDto,
|
||||||
AlbumInfoDto,
|
AlbumInfoDto,
|
||||||
|
|
@ -26,9 +27,10 @@ export class AlbumController {
|
||||||
|
|
||||||
@Get()
|
@Get()
|
||||||
@Authenticated({ permission: Permission.AlbumRead })
|
@Authenticated({ permission: Permission.AlbumRead })
|
||||||
@ApiOperation({
|
@Endpoint({
|
||||||
summary: 'List all albums',
|
summary: 'List all albums',
|
||||||
description: 'Retrieve a list of albums available to the authenticated user.',
|
description: 'Retrieve a list of albums available to the authenticated user.',
|
||||||
|
history: new HistoryBuilder().added('v1').beta('v1').stable('v2'),
|
||||||
})
|
})
|
||||||
getAllAlbums(@Auth() auth: AuthDto, @Query() query: GetAlbumsDto): Promise<AlbumResponseDto[]> {
|
getAllAlbums(@Auth() auth: AuthDto, @Query() query: GetAlbumsDto): Promise<AlbumResponseDto[]> {
|
||||||
return this.service.getAll(auth, query);
|
return this.service.getAll(auth, query);
|
||||||
|
|
@ -36,9 +38,10 @@ export class AlbumController {
|
||||||
|
|
||||||
@Post()
|
@Post()
|
||||||
@Authenticated({ permission: Permission.AlbumCreate })
|
@Authenticated({ permission: Permission.AlbumCreate })
|
||||||
@ApiOperation({
|
@Endpoint({
|
||||||
summary: 'Create an album',
|
summary: 'Create an album',
|
||||||
description: 'Create a new album. The album can also be created with initial users and assets.',
|
description: 'Create a new album. The album can also be created with initial users and assets.',
|
||||||
|
history: new HistoryBuilder().added('v1').beta('v1').stable('v2'),
|
||||||
})
|
})
|
||||||
createAlbum(@Auth() auth: AuthDto, @Body() dto: CreateAlbumDto): Promise<AlbumResponseDto> {
|
createAlbum(@Auth() auth: AuthDto, @Body() dto: CreateAlbumDto): Promise<AlbumResponseDto> {
|
||||||
return this.service.create(auth, dto);
|
return this.service.create(auth, dto);
|
||||||
|
|
@ -46,9 +49,10 @@ export class AlbumController {
|
||||||
|
|
||||||
@Get('statistics')
|
@Get('statistics')
|
||||||
@Authenticated({ permission: Permission.AlbumStatistics })
|
@Authenticated({ permission: Permission.AlbumStatistics })
|
||||||
@ApiOperation({
|
@Endpoint({
|
||||||
summary: 'Retrieve album statistics',
|
summary: 'Retrieve album statistics',
|
||||||
description: 'Returns statistics about the albums available to the authenticated user.',
|
description: 'Returns statistics about the albums available to the authenticated user.',
|
||||||
|
history: new HistoryBuilder().added('v1').beta('v1').stable('v2'),
|
||||||
})
|
})
|
||||||
getAlbumStatistics(@Auth() auth: AuthDto): Promise<AlbumStatisticsResponseDto> {
|
getAlbumStatistics(@Auth() auth: AuthDto): Promise<AlbumStatisticsResponseDto> {
|
||||||
return this.service.getStatistics(auth);
|
return this.service.getStatistics(auth);
|
||||||
|
|
@ -56,9 +60,10 @@ export class AlbumController {
|
||||||
|
|
||||||
@Authenticated({ permission: Permission.AlbumRead, sharedLink: true })
|
@Authenticated({ permission: Permission.AlbumRead, sharedLink: true })
|
||||||
@Get(':id')
|
@Get(':id')
|
||||||
@ApiOperation({
|
@Endpoint({
|
||||||
summary: 'Retrieve an album',
|
summary: 'Retrieve an album',
|
||||||
description: 'Retrieve information about a specific album by its ID.',
|
description: 'Retrieve information about a specific album by its ID.',
|
||||||
|
history: new HistoryBuilder().added('v1').beta('v1').stable('v2'),
|
||||||
})
|
})
|
||||||
getAlbumInfo(
|
getAlbumInfo(
|
||||||
@Auth() auth: AuthDto,
|
@Auth() auth: AuthDto,
|
||||||
|
|
@ -70,10 +75,11 @@ export class AlbumController {
|
||||||
|
|
||||||
@Patch(':id')
|
@Patch(':id')
|
||||||
@Authenticated({ permission: Permission.AlbumUpdate })
|
@Authenticated({ permission: Permission.AlbumUpdate })
|
||||||
@ApiOperation({
|
@Endpoint({
|
||||||
summary: 'Update an album',
|
summary: 'Update an album',
|
||||||
description:
|
description:
|
||||||
'Update the information of a specific album by its ID. This endpoint can be used to update the album name, description, sort order, etc. However, it is not used to add or remove assets or users from the album.',
|
'Update the information of a specific album by its ID. This endpoint can be used to update the album name, description, sort order, etc. However, it is not used to add or remove assets or users from the album.',
|
||||||
|
history: new HistoryBuilder().added('v1').beta('v1').stable('v2'),
|
||||||
})
|
})
|
||||||
updateAlbumInfo(
|
updateAlbumInfo(
|
||||||
@Auth() auth: AuthDto,
|
@Auth() auth: AuthDto,
|
||||||
|
|
@ -86,10 +92,11 @@ export class AlbumController {
|
||||||
@Delete(':id')
|
@Delete(':id')
|
||||||
@Authenticated({ permission: Permission.AlbumDelete })
|
@Authenticated({ permission: Permission.AlbumDelete })
|
||||||
@HttpCode(HttpStatus.NO_CONTENT)
|
@HttpCode(HttpStatus.NO_CONTENT)
|
||||||
@ApiOperation({
|
@Endpoint({
|
||||||
summary: 'Delete an album',
|
summary: 'Delete an album',
|
||||||
description:
|
description:
|
||||||
'Delete a specific album by its ID. Note the album is initially trashed and then immediately scheduled for deletion, but relies on a background job to complete the process.',
|
'Delete a specific album by its ID. Note the album is initially trashed and then immediately scheduled for deletion, but relies on a background job to complete the process.',
|
||||||
|
history: new HistoryBuilder().added('v1').beta('v1').stable('v2'),
|
||||||
})
|
})
|
||||||
deleteAlbum(@Auth() auth: AuthDto, @Param() { id }: UUIDParamDto) {
|
deleteAlbum(@Auth() auth: AuthDto, @Param() { id }: UUIDParamDto) {
|
||||||
return this.service.delete(auth, id);
|
return this.service.delete(auth, id);
|
||||||
|
|
@ -97,9 +104,10 @@ export class AlbumController {
|
||||||
|
|
||||||
@Put(':id/assets')
|
@Put(':id/assets')
|
||||||
@Authenticated({ permission: Permission.AlbumAssetCreate, sharedLink: true })
|
@Authenticated({ permission: Permission.AlbumAssetCreate, sharedLink: true })
|
||||||
@ApiOperation({
|
@Endpoint({
|
||||||
summary: 'Add assets to an album',
|
summary: 'Add assets to an album',
|
||||||
description: 'Add multiple assets to a specific album by its ID.',
|
description: 'Add multiple assets to a specific album by its ID.',
|
||||||
|
history: new HistoryBuilder().added('v1').beta('v1').stable('v2'),
|
||||||
})
|
})
|
||||||
addAssetsToAlbum(
|
addAssetsToAlbum(
|
||||||
@Auth() auth: AuthDto,
|
@Auth() auth: AuthDto,
|
||||||
|
|
@ -111,9 +119,10 @@ export class AlbumController {
|
||||||
|
|
||||||
@Put('assets')
|
@Put('assets')
|
||||||
@Authenticated({ permission: Permission.AlbumAssetCreate, sharedLink: true })
|
@Authenticated({ permission: Permission.AlbumAssetCreate, sharedLink: true })
|
||||||
@ApiOperation({
|
@Endpoint({
|
||||||
summary: 'Add assets to albums',
|
summary: 'Add assets to albums',
|
||||||
description: 'Send a list of asset IDs and album IDs to add each asset to each album.',
|
description: 'Send a list of asset IDs and album IDs to add each asset to each album.',
|
||||||
|
history: new HistoryBuilder().added('v1').beta('v1').stable('v2'),
|
||||||
})
|
})
|
||||||
addAssetsToAlbums(@Auth() auth: AuthDto, @Body() dto: AlbumsAddAssetsDto): Promise<AlbumsAddAssetsResponseDto> {
|
addAssetsToAlbums(@Auth() auth: AuthDto, @Body() dto: AlbumsAddAssetsDto): Promise<AlbumsAddAssetsResponseDto> {
|
||||||
return this.service.addAssetsToAlbums(auth, dto);
|
return this.service.addAssetsToAlbums(auth, dto);
|
||||||
|
|
@ -121,9 +130,10 @@ export class AlbumController {
|
||||||
|
|
||||||
@Delete(':id/assets')
|
@Delete(':id/assets')
|
||||||
@Authenticated({ permission: Permission.AlbumAssetDelete })
|
@Authenticated({ permission: Permission.AlbumAssetDelete })
|
||||||
@ApiOperation({
|
@Endpoint({
|
||||||
summary: 'Remove assets from an album',
|
summary: 'Remove assets from an album',
|
||||||
description: 'Remove multiple assets from a specific album by its ID.',
|
description: 'Remove multiple assets from a specific album by its ID.',
|
||||||
|
history: new HistoryBuilder().added('v1').beta('v1').stable('v2'),
|
||||||
})
|
})
|
||||||
removeAssetFromAlbum(
|
removeAssetFromAlbum(
|
||||||
@Auth() auth: AuthDto,
|
@Auth() auth: AuthDto,
|
||||||
|
|
@ -135,9 +145,10 @@ export class AlbumController {
|
||||||
|
|
||||||
@Put(':id/users')
|
@Put(':id/users')
|
||||||
@Authenticated({ permission: Permission.AlbumUserCreate })
|
@Authenticated({ permission: Permission.AlbumUserCreate })
|
||||||
@ApiOperation({
|
@Endpoint({
|
||||||
summary: 'Share album with users',
|
summary: 'Share album with users',
|
||||||
description: 'Share an album with multiple users. Each user can be given a specific role in the album.',
|
description: 'Share an album with multiple users. Each user can be given a specific role in the album.',
|
||||||
|
history: new HistoryBuilder().added('v1').beta('v1').stable('v2'),
|
||||||
})
|
})
|
||||||
addUsersToAlbum(
|
addUsersToAlbum(
|
||||||
@Auth() auth: AuthDto,
|
@Auth() auth: AuthDto,
|
||||||
|
|
@ -150,9 +161,10 @@ export class AlbumController {
|
||||||
@Put(':id/user/:userId')
|
@Put(':id/user/:userId')
|
||||||
@Authenticated({ permission: Permission.AlbumUserUpdate })
|
@Authenticated({ permission: Permission.AlbumUserUpdate })
|
||||||
@HttpCode(HttpStatus.NO_CONTENT)
|
@HttpCode(HttpStatus.NO_CONTENT)
|
||||||
@ApiOperation({
|
@Endpoint({
|
||||||
summary: 'Update user role',
|
summary: 'Update user role',
|
||||||
description: 'Change the role for a specific user in a specific album.',
|
description: 'Change the role for a specific user in a specific album.',
|
||||||
|
history: new HistoryBuilder().added('v1').beta('v1').stable('v2'),
|
||||||
})
|
})
|
||||||
updateAlbumUser(
|
updateAlbumUser(
|
||||||
@Auth() auth: AuthDto,
|
@Auth() auth: AuthDto,
|
||||||
|
|
@ -166,9 +178,10 @@ export class AlbumController {
|
||||||
@Delete(':id/user/:userId')
|
@Delete(':id/user/:userId')
|
||||||
@Authenticated({ permission: Permission.AlbumUserDelete })
|
@Authenticated({ permission: Permission.AlbumUserDelete })
|
||||||
@HttpCode(HttpStatus.NO_CONTENT)
|
@HttpCode(HttpStatus.NO_CONTENT)
|
||||||
@ApiOperation({
|
@Endpoint({
|
||||||
summary: 'Remove user from album',
|
summary: 'Remove user from album',
|
||||||
description: 'Remove a user from an album. Use an ID of "me" to leave a shared album.',
|
description: 'Remove a user from an album. Use an ID of "me" to leave a shared album.',
|
||||||
|
history: new HistoryBuilder().added('v1').beta('v1').stable('v2'),
|
||||||
})
|
})
|
||||||
removeUserFromAlbum(
|
removeUserFromAlbum(
|
||||||
@Auth() auth: AuthDto,
|
@Auth() auth: AuthDto,
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,6 @@
|
||||||
import { Body, Controller, Delete, Get, HttpCode, HttpStatus, Param, Post, Put } from '@nestjs/common';
|
import { Body, Controller, Delete, Get, HttpCode, HttpStatus, Param, Post, Put } from '@nestjs/common';
|
||||||
import { ApiOperation, ApiTags } from '@nestjs/swagger';
|
import { ApiTags } from '@nestjs/swagger';
|
||||||
|
import { Endpoint, HistoryBuilder } from 'src/decorators';
|
||||||
import { APIKeyCreateDto, APIKeyCreateResponseDto, APIKeyResponseDto, APIKeyUpdateDto } from 'src/dtos/api-key.dto';
|
import { APIKeyCreateDto, APIKeyCreateResponseDto, APIKeyResponseDto, APIKeyUpdateDto } from 'src/dtos/api-key.dto';
|
||||||
import { AuthDto } from 'src/dtos/auth.dto';
|
import { AuthDto } from 'src/dtos/auth.dto';
|
||||||
import { ApiTag, Permission } from 'src/enum';
|
import { ApiTag, Permission } from 'src/enum';
|
||||||
|
|
@ -14,9 +15,10 @@ export class ApiKeyController {
|
||||||
|
|
||||||
@Post()
|
@Post()
|
||||||
@Authenticated({ permission: Permission.ApiKeyCreate })
|
@Authenticated({ permission: Permission.ApiKeyCreate })
|
||||||
@ApiOperation({
|
@Endpoint({
|
||||||
summary: 'Create an API key',
|
summary: 'Create an API key',
|
||||||
description: 'Creates a new API key. It will be limited to the permissions specified.',
|
description: 'Creates a new API key. It will be limited to the permissions specified.',
|
||||||
|
history: new HistoryBuilder().added('v1').beta('v1').stable('v2'),
|
||||||
})
|
})
|
||||||
createApiKey(@Auth() auth: AuthDto, @Body() dto: APIKeyCreateDto): Promise<APIKeyCreateResponseDto> {
|
createApiKey(@Auth() auth: AuthDto, @Body() dto: APIKeyCreateDto): Promise<APIKeyCreateResponseDto> {
|
||||||
return this.service.create(auth, dto);
|
return this.service.create(auth, dto);
|
||||||
|
|
@ -24,16 +26,21 @@ export class ApiKeyController {
|
||||||
|
|
||||||
@Get()
|
@Get()
|
||||||
@Authenticated({ permission: Permission.ApiKeyRead })
|
@Authenticated({ permission: Permission.ApiKeyRead })
|
||||||
@ApiOperation({ summary: 'List all API keys', description: 'Retrieve all API keys of the current user.' })
|
@Endpoint({
|
||||||
|
summary: 'List all API keys',
|
||||||
|
description: 'Retrieve all API keys of the current user.',
|
||||||
|
history: new HistoryBuilder().added('v1').beta('v1').stable('v2'),
|
||||||
|
})
|
||||||
getApiKeys(@Auth() auth: AuthDto): Promise<APIKeyResponseDto[]> {
|
getApiKeys(@Auth() auth: AuthDto): Promise<APIKeyResponseDto[]> {
|
||||||
return this.service.getAll(auth);
|
return this.service.getAll(auth);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Get('me')
|
@Get('me')
|
||||||
@Authenticated({ permission: false })
|
@Authenticated({ permission: false })
|
||||||
@ApiOperation({
|
@Endpoint({
|
||||||
summary: 'Retrieve the current API key',
|
summary: 'Retrieve the current API key',
|
||||||
description: 'Retrieve the API key that is used to access this endpoint.',
|
description: 'Retrieve the API key that is used to access this endpoint.',
|
||||||
|
history: new HistoryBuilder().added('v1').beta('v1').stable('v2'),
|
||||||
})
|
})
|
||||||
async getMyApiKey(@Auth() auth: AuthDto): Promise<APIKeyResponseDto> {
|
async getMyApiKey(@Auth() auth: AuthDto): Promise<APIKeyResponseDto> {
|
||||||
return this.service.getMine(auth);
|
return this.service.getMine(auth);
|
||||||
|
|
@ -41,9 +48,10 @@ export class ApiKeyController {
|
||||||
|
|
||||||
@Get(':id')
|
@Get(':id')
|
||||||
@Authenticated({ permission: Permission.ApiKeyRead })
|
@Authenticated({ permission: Permission.ApiKeyRead })
|
||||||
@ApiOperation({
|
@Endpoint({
|
||||||
summary: 'Retrieve an API key',
|
summary: 'Retrieve an API key',
|
||||||
description: 'Retrieve an API key by its ID. The current user must own this API key.',
|
description: 'Retrieve an API key by its ID. The current user must own this API key.',
|
||||||
|
history: new HistoryBuilder().added('v1').beta('v1').stable('v2'),
|
||||||
})
|
})
|
||||||
getApiKey(@Auth() auth: AuthDto, @Param() { id }: UUIDParamDto): Promise<APIKeyResponseDto> {
|
getApiKey(@Auth() auth: AuthDto, @Param() { id }: UUIDParamDto): Promise<APIKeyResponseDto> {
|
||||||
return this.service.getById(auth, id);
|
return this.service.getById(auth, id);
|
||||||
|
|
@ -51,9 +59,10 @@ export class ApiKeyController {
|
||||||
|
|
||||||
@Put(':id')
|
@Put(':id')
|
||||||
@Authenticated({ permission: Permission.ApiKeyUpdate })
|
@Authenticated({ permission: Permission.ApiKeyUpdate })
|
||||||
@ApiOperation({
|
@Endpoint({
|
||||||
summary: 'Update an API key',
|
summary: 'Update an API key',
|
||||||
description: 'Updates the name and permissions of an API key by its ID. The current user must own this API key.',
|
description: 'Updates the name and permissions of an API key by its ID. The current user must own this API key.',
|
||||||
|
history: new HistoryBuilder().added('v1').beta('v1').stable('v2'),
|
||||||
})
|
})
|
||||||
updateApiKey(
|
updateApiKey(
|
||||||
@Auth() auth: AuthDto,
|
@Auth() auth: AuthDto,
|
||||||
|
|
@ -66,9 +75,10 @@ export class ApiKeyController {
|
||||||
@Delete(':id')
|
@Delete(':id')
|
||||||
@Authenticated({ permission: Permission.ApiKeyDelete })
|
@Authenticated({ permission: Permission.ApiKeyDelete })
|
||||||
@HttpCode(HttpStatus.NO_CONTENT)
|
@HttpCode(HttpStatus.NO_CONTENT)
|
||||||
@ApiOperation({
|
@Endpoint({
|
||||||
summary: 'Delete an API key',
|
summary: 'Delete an API key',
|
||||||
description: 'Deletes an API key identified by its ID. The current user must own this API key.',
|
description: 'Deletes an API key identified by its ID. The current user must own this API key.',
|
||||||
|
history: new HistoryBuilder().added('v1').beta('v1').stable('v2'),
|
||||||
})
|
})
|
||||||
deleteApiKey(@Auth() auth: AuthDto, @Param() { id }: UUIDParamDto): Promise<void> {
|
deleteApiKey(@Auth() auth: AuthDto, @Param() { id }: UUIDParamDto): Promise<void> {
|
||||||
return this.service.delete(auth, id);
|
return this.service.delete(auth, id);
|
||||||
|
|
|
||||||
|
|
@ -15,9 +15,9 @@ import {
|
||||||
UploadedFiles,
|
UploadedFiles,
|
||||||
UseInterceptors,
|
UseInterceptors,
|
||||||
} from '@nestjs/common';
|
} from '@nestjs/common';
|
||||||
import { ApiBody, ApiConsumes, ApiHeader, ApiOperation, ApiTags } from '@nestjs/swagger';
|
import { ApiBody, ApiConsumes, ApiHeader, ApiTags } from '@nestjs/swagger';
|
||||||
import { NextFunction, Request, Response } from 'express';
|
import { NextFunction, Request, Response } from 'express';
|
||||||
import { EndpointLifecycle } from 'src/decorators';
|
import { Endpoint, HistoryBuilder } from 'src/decorators';
|
||||||
import {
|
import {
|
||||||
AssetBulkUploadCheckResponseDto,
|
AssetBulkUploadCheckResponseDto,
|
||||||
AssetMediaResponseDto,
|
AssetMediaResponseDto,
|
||||||
|
|
@ -62,9 +62,10 @@ export class AssetMediaController {
|
||||||
required: false,
|
required: false,
|
||||||
})
|
})
|
||||||
@ApiBody({ description: 'Asset Upload Information', type: AssetMediaCreateDto })
|
@ApiBody({ description: 'Asset Upload Information', type: AssetMediaCreateDto })
|
||||||
@ApiOperation({
|
@Endpoint({
|
||||||
summary: 'Upload asset',
|
summary: 'Upload asset',
|
||||||
description: 'Uploads a new asset to the server.',
|
description: 'Uploads a new asset to the server.',
|
||||||
|
history: new HistoryBuilder().added('v1').beta('v1').stable('v2'),
|
||||||
})
|
})
|
||||||
async uploadAsset(
|
async uploadAsset(
|
||||||
@Auth() auth: AuthDto,
|
@Auth() auth: AuthDto,
|
||||||
|
|
@ -85,9 +86,10 @@ export class AssetMediaController {
|
||||||
@Get(':id/original')
|
@Get(':id/original')
|
||||||
@FileResponse()
|
@FileResponse()
|
||||||
@Authenticated({ permission: Permission.AssetDownload, sharedLink: true })
|
@Authenticated({ permission: Permission.AssetDownload, sharedLink: true })
|
||||||
@ApiOperation({
|
@Endpoint({
|
||||||
summary: 'Download original asset',
|
summary: 'Download original asset',
|
||||||
description: 'Downloads the original file of the specified asset.',
|
description: 'Downloads the original file of the specified asset.',
|
||||||
|
history: new HistoryBuilder().added('v1').beta('v1').stable('v2'),
|
||||||
})
|
})
|
||||||
async downloadAsset(
|
async downloadAsset(
|
||||||
@Auth() auth: AuthDto,
|
@Auth() auth: AuthDto,
|
||||||
|
|
@ -101,11 +103,10 @@ export class AssetMediaController {
|
||||||
@Put(':id/original')
|
@Put(':id/original')
|
||||||
@UseInterceptors(FileUploadInterceptor)
|
@UseInterceptors(FileUploadInterceptor)
|
||||||
@ApiConsumes('multipart/form-data')
|
@ApiConsumes('multipart/form-data')
|
||||||
@EndpointLifecycle({
|
@Endpoint({
|
||||||
addedAt: 'v1.106.0',
|
|
||||||
deprecatedAt: 'v1.142.0',
|
|
||||||
summary: 'Replace asset',
|
summary: 'Replace asset',
|
||||||
description: 'Replace the asset with new file, without changing its id.',
|
description: 'Replace the asset with new file, without changing its id.',
|
||||||
|
history: new HistoryBuilder().added('v1').deprecated('v1', { replacementId: 'copyAsset' }),
|
||||||
})
|
})
|
||||||
@Authenticated({ permission: Permission.AssetReplace, sharedLink: true })
|
@Authenticated({ permission: Permission.AssetReplace, sharedLink: true })
|
||||||
async replaceAsset(
|
async replaceAsset(
|
||||||
|
|
@ -127,9 +128,10 @@ export class AssetMediaController {
|
||||||
@Get(':id/thumbnail')
|
@Get(':id/thumbnail')
|
||||||
@FileResponse()
|
@FileResponse()
|
||||||
@Authenticated({ permission: Permission.AssetView, sharedLink: true })
|
@Authenticated({ permission: Permission.AssetView, sharedLink: true })
|
||||||
@ApiOperation({
|
@Endpoint({
|
||||||
summary: 'View asset thumbnail',
|
summary: 'View asset thumbnail',
|
||||||
description: 'Retrieve the thumbnail image for the specified asset.',
|
description: 'Retrieve the thumbnail image for the specified asset.',
|
||||||
|
history: new HistoryBuilder().added('v1').beta('v1').stable('v2'),
|
||||||
})
|
})
|
||||||
async viewAsset(
|
async viewAsset(
|
||||||
@Auth() auth: AuthDto,
|
@Auth() auth: AuthDto,
|
||||||
|
|
@ -168,9 +170,10 @@ export class AssetMediaController {
|
||||||
@Get(':id/video/playback')
|
@Get(':id/video/playback')
|
||||||
@FileResponse()
|
@FileResponse()
|
||||||
@Authenticated({ permission: Permission.AssetView, sharedLink: true })
|
@Authenticated({ permission: Permission.AssetView, sharedLink: true })
|
||||||
@ApiOperation({
|
@Endpoint({
|
||||||
summary: 'Play asset video',
|
summary: 'Play asset video',
|
||||||
description: 'Streams the video file for the specified asset. This endpoint also supports byte range requests.',
|
description: 'Streams the video file for the specified asset. This endpoint also supports byte range requests.',
|
||||||
|
history: new HistoryBuilder().added('v1').beta('v1').stable('v2'),
|
||||||
})
|
})
|
||||||
async playAssetVideo(
|
async playAssetVideo(
|
||||||
@Auth() auth: AuthDto,
|
@Auth() auth: AuthDto,
|
||||||
|
|
@ -181,14 +184,12 @@ export class AssetMediaController {
|
||||||
await sendFile(res, next, () => this.service.playbackVideo(auth, id), this.logger);
|
await sendFile(res, next, () => this.service.playbackVideo(auth, id), this.logger);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Checks if multiple assets exist on the server and returns all existing - used by background backup
|
|
||||||
*/
|
|
||||||
@Post('exist')
|
@Post('exist')
|
||||||
@Authenticated()
|
@Authenticated()
|
||||||
@ApiOperation({
|
@Endpoint({
|
||||||
summary: 'Check existing assets',
|
summary: 'Check existing assets',
|
||||||
description: 'Checks if multiple assets exist on the server and returns all existing - used by background backup',
|
description: 'Checks if multiple assets exist on the server and returns all existing - used by background backup',
|
||||||
|
history: new HistoryBuilder().added('v1').beta('v1').stable('v2'),
|
||||||
})
|
})
|
||||||
@HttpCode(HttpStatus.OK)
|
@HttpCode(HttpStatus.OK)
|
||||||
checkExistingAssets(
|
checkExistingAssets(
|
||||||
|
|
@ -198,14 +199,12 @@ export class AssetMediaController {
|
||||||
return this.service.checkExistingAssets(auth, dto);
|
return this.service.checkExistingAssets(auth, dto);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Checks if assets exist by checksums
|
|
||||||
*/
|
|
||||||
@Post('bulk-upload-check')
|
@Post('bulk-upload-check')
|
||||||
@Authenticated({ permission: Permission.AssetUpload })
|
@Authenticated({ permission: Permission.AssetUpload })
|
||||||
@ApiOperation({
|
@Endpoint({
|
||||||
summary: 'Check bulk upload',
|
summary: 'Check bulk upload',
|
||||||
description: 'Determine which assets have already been uploaded to the server based on their SHA1 checksums.',
|
description: 'Determine which assets have already been uploaded to the server based on their SHA1 checksums.',
|
||||||
|
history: new HistoryBuilder().added('v1').beta('v1').stable('v2'),
|
||||||
})
|
})
|
||||||
@HttpCode(HttpStatus.OK)
|
@HttpCode(HttpStatus.OK)
|
||||||
checkBulkUpload(
|
checkBulkUpload(
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
import { Body, Controller, Delete, Get, HttpCode, HttpStatus, Param, Post, Put, Query } from '@nestjs/common';
|
import { Body, Controller, Delete, Get, HttpCode, HttpStatus, Param, Post, Put, Query } from '@nestjs/common';
|
||||||
import { ApiOperation, ApiTags } from '@nestjs/swagger';
|
import { ApiTags } from '@nestjs/swagger';
|
||||||
import { EndpointLifecycle } from 'src/decorators';
|
import { Endpoint, HistoryBuilder } from 'src/decorators';
|
||||||
import { AssetResponseDto } from 'src/dtos/asset-response.dto';
|
import { AssetResponseDto } from 'src/dtos/asset-response.dto';
|
||||||
import {
|
import {
|
||||||
AssetBulkDeleteDto,
|
AssetBulkDeleteDto,
|
||||||
|
|
@ -30,20 +30,20 @@ export class AssetController {
|
||||||
|
|
||||||
@Get('random')
|
@Get('random')
|
||||||
@Authenticated({ permission: Permission.AssetRead })
|
@Authenticated({ permission: Permission.AssetRead })
|
||||||
@EndpointLifecycle({
|
@Endpoint({
|
||||||
deprecatedAt: 'v1.116.0',
|
|
||||||
summary: 'Get random assets',
|
summary: 'Get random assets',
|
||||||
description: 'Retrieve a specified number of random assets for the authenticated user.',
|
description: 'Retrieve a specified number of random assets for the authenticated user.',
|
||||||
|
history: new HistoryBuilder().added('v1').deprecated('v1', { replacementId: 'searchAssets' }),
|
||||||
})
|
})
|
||||||
getRandom(@Auth() auth: AuthDto, @Query() dto: RandomAssetsDto): Promise<AssetResponseDto[]> {
|
getRandom(@Auth() auth: AuthDto, @Query() dto: RandomAssetsDto): Promise<AssetResponseDto[]> {
|
||||||
return this.service.getRandom(auth, dto.count ?? 1);
|
return this.service.getRandom(auth, dto.count ?? 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Get('/device/:deviceId')
|
@Get('/device/:deviceId')
|
||||||
@EndpointLifecycle({
|
@Endpoint({
|
||||||
deprecatedAt: 'v2.0.0',
|
|
||||||
summary: 'Retrieve assets by device ID',
|
summary: 'Retrieve assets by device ID',
|
||||||
description: 'Get all asset of a device that are in the database, ID only.',
|
description: 'Get all asset of a device that are in the database, ID only.',
|
||||||
|
history: new HistoryBuilder().added('v1').deprecated('v2'),
|
||||||
})
|
})
|
||||||
@Authenticated()
|
@Authenticated()
|
||||||
getAllUserAssetsByDeviceId(@Auth() auth: AuthDto, @Param() { deviceId }: DeviceIdDto) {
|
getAllUserAssetsByDeviceId(@Auth() auth: AuthDto, @Param() { deviceId }: DeviceIdDto) {
|
||||||
|
|
@ -52,9 +52,10 @@ export class AssetController {
|
||||||
|
|
||||||
@Get('statistics')
|
@Get('statistics')
|
||||||
@Authenticated({ permission: Permission.AssetStatistics })
|
@Authenticated({ permission: Permission.AssetStatistics })
|
||||||
@ApiOperation({
|
@Endpoint({
|
||||||
summary: 'Get asset statistics',
|
summary: 'Get asset statistics',
|
||||||
description: 'Retrieve various statistics about the assets owned by the authenticated user.',
|
description: 'Retrieve various statistics about the assets owned by the authenticated user.',
|
||||||
|
history: new HistoryBuilder().added('v1').beta('v1').stable('v2'),
|
||||||
})
|
})
|
||||||
getAssetStatistics(@Auth() auth: AuthDto, @Query() dto: AssetStatsDto): Promise<AssetStatsResponseDto> {
|
getAssetStatistics(@Auth() auth: AuthDto, @Query() dto: AssetStatsDto): Promise<AssetStatsResponseDto> {
|
||||||
return this.service.getStatistics(auth, dto);
|
return this.service.getStatistics(auth, dto);
|
||||||
|
|
@ -63,9 +64,10 @@ export class AssetController {
|
||||||
@Post('jobs')
|
@Post('jobs')
|
||||||
@Authenticated()
|
@Authenticated()
|
||||||
@HttpCode(HttpStatus.NO_CONTENT)
|
@HttpCode(HttpStatus.NO_CONTENT)
|
||||||
@ApiOperation({
|
@Endpoint({
|
||||||
summary: 'Run an asset job',
|
summary: 'Run an asset job',
|
||||||
description: 'Run a specific job on a set of assets.',
|
description: 'Run a specific job on a set of assets.',
|
||||||
|
history: new HistoryBuilder().added('v1').beta('v1').stable('v2'),
|
||||||
})
|
})
|
||||||
runAssetJobs(@Auth() auth: AuthDto, @Body() dto: AssetJobsDto): Promise<void> {
|
runAssetJobs(@Auth() auth: AuthDto, @Body() dto: AssetJobsDto): Promise<void> {
|
||||||
return this.service.run(auth, dto);
|
return this.service.run(auth, dto);
|
||||||
|
|
@ -74,9 +76,10 @@ export class AssetController {
|
||||||
@Put()
|
@Put()
|
||||||
@Authenticated({ permission: Permission.AssetUpdate })
|
@Authenticated({ permission: Permission.AssetUpdate })
|
||||||
@HttpCode(HttpStatus.NO_CONTENT)
|
@HttpCode(HttpStatus.NO_CONTENT)
|
||||||
@ApiOperation({
|
@Endpoint({
|
||||||
summary: 'Update assets',
|
summary: 'Update assets',
|
||||||
description: 'Updates multiple assets at the same time.',
|
description: 'Updates multiple assets at the same time.',
|
||||||
|
history: new HistoryBuilder().added('v1').beta('v1').stable('v2'),
|
||||||
})
|
})
|
||||||
updateAssets(@Auth() auth: AuthDto, @Body() dto: AssetBulkUpdateDto): Promise<void> {
|
updateAssets(@Auth() auth: AuthDto, @Body() dto: AssetBulkUpdateDto): Promise<void> {
|
||||||
return this.service.updateAll(auth, dto);
|
return this.service.updateAll(auth, dto);
|
||||||
|
|
@ -85,9 +88,10 @@ export class AssetController {
|
||||||
@Delete()
|
@Delete()
|
||||||
@Authenticated({ permission: Permission.AssetDelete })
|
@Authenticated({ permission: Permission.AssetDelete })
|
||||||
@HttpCode(HttpStatus.NO_CONTENT)
|
@HttpCode(HttpStatus.NO_CONTENT)
|
||||||
@ApiOperation({
|
@Endpoint({
|
||||||
summary: 'Delete assets',
|
summary: 'Delete assets',
|
||||||
description: 'Deletes multiple assets at the same time.',
|
description: 'Deletes multiple assets at the same time.',
|
||||||
|
history: new HistoryBuilder().added('v1').beta('v1').stable('v2'),
|
||||||
})
|
})
|
||||||
deleteAssets(@Auth() auth: AuthDto, @Body() dto: AssetBulkDeleteDto): Promise<void> {
|
deleteAssets(@Auth() auth: AuthDto, @Body() dto: AssetBulkDeleteDto): Promise<void> {
|
||||||
return this.service.deleteAll(auth, dto);
|
return this.service.deleteAll(auth, dto);
|
||||||
|
|
@ -95,9 +99,10 @@ export class AssetController {
|
||||||
|
|
||||||
@Get(':id')
|
@Get(':id')
|
||||||
@Authenticated({ permission: Permission.AssetRead, sharedLink: true })
|
@Authenticated({ permission: Permission.AssetRead, sharedLink: true })
|
||||||
@ApiOperation({
|
@Endpoint({
|
||||||
summary: 'Retrieve an asset',
|
summary: 'Retrieve an asset',
|
||||||
description: 'Retrieve detailed information about a specific asset.',
|
description: 'Retrieve detailed information about a specific asset.',
|
||||||
|
history: new HistoryBuilder().added('v1').beta('v1').stable('v2'),
|
||||||
})
|
})
|
||||||
getAssetInfo(@Auth() auth: AuthDto, @Param() { id }: UUIDParamDto): Promise<AssetResponseDto> {
|
getAssetInfo(@Auth() auth: AuthDto, @Param() { id }: UUIDParamDto): Promise<AssetResponseDto> {
|
||||||
return this.service.get(auth, id) as Promise<AssetResponseDto>;
|
return this.service.get(auth, id) as Promise<AssetResponseDto>;
|
||||||
|
|
@ -106,9 +111,10 @@ export class AssetController {
|
||||||
@Put('copy')
|
@Put('copy')
|
||||||
@Authenticated({ permission: Permission.AssetCopy })
|
@Authenticated({ permission: Permission.AssetCopy })
|
||||||
@HttpCode(HttpStatus.NO_CONTENT)
|
@HttpCode(HttpStatus.NO_CONTENT)
|
||||||
@ApiOperation({
|
@Endpoint({
|
||||||
summary: 'Copy asset',
|
summary: 'Copy asset',
|
||||||
description: 'Copy asset information like albums, tags, etc. from one asset to another.',
|
description: 'Copy asset information like albums, tags, etc. from one asset to another.',
|
||||||
|
history: new HistoryBuilder().added('v1').beta('v1').stable('v2'),
|
||||||
})
|
})
|
||||||
copyAsset(@Auth() auth: AuthDto, @Body() dto: AssetCopyDto): Promise<void> {
|
copyAsset(@Auth() auth: AuthDto, @Body() dto: AssetCopyDto): Promise<void> {
|
||||||
return this.service.copy(auth, dto);
|
return this.service.copy(auth, dto);
|
||||||
|
|
@ -116,9 +122,10 @@ export class AssetController {
|
||||||
|
|
||||||
@Put(':id')
|
@Put(':id')
|
||||||
@Authenticated({ permission: Permission.AssetUpdate })
|
@Authenticated({ permission: Permission.AssetUpdate })
|
||||||
@ApiOperation({
|
@Endpoint({
|
||||||
summary: 'Update an asset',
|
summary: 'Update an asset',
|
||||||
description: 'Update information of a specific asset.',
|
description: 'Update information of a specific asset.',
|
||||||
|
history: new HistoryBuilder().added('v1').beta('v1').stable('v2'),
|
||||||
})
|
})
|
||||||
updateAsset(
|
updateAsset(
|
||||||
@Auth() auth: AuthDto,
|
@Auth() auth: AuthDto,
|
||||||
|
|
@ -130,9 +137,10 @@ export class AssetController {
|
||||||
|
|
||||||
@Get(':id/metadata')
|
@Get(':id/metadata')
|
||||||
@Authenticated({ permission: Permission.AssetRead })
|
@Authenticated({ permission: Permission.AssetRead })
|
||||||
@ApiOperation({
|
@Endpoint({
|
||||||
summary: 'Get asset metadata',
|
summary: 'Get asset metadata',
|
||||||
description: 'Retrieve all metadata key-value pairs associated with the specified asset.',
|
description: 'Retrieve all metadata key-value pairs associated with the specified asset.',
|
||||||
|
history: new HistoryBuilder().added('v1').beta('v1').stable('v2'),
|
||||||
})
|
})
|
||||||
getAssetMetadata(@Auth() auth: AuthDto, @Param() { id }: UUIDParamDto): Promise<AssetMetadataResponseDto[]> {
|
getAssetMetadata(@Auth() auth: AuthDto, @Param() { id }: UUIDParamDto): Promise<AssetMetadataResponseDto[]> {
|
||||||
return this.service.getMetadata(auth, id);
|
return this.service.getMetadata(auth, id);
|
||||||
|
|
@ -140,9 +148,10 @@ export class AssetController {
|
||||||
|
|
||||||
@Get(':id/ocr')
|
@Get(':id/ocr')
|
||||||
@Authenticated({ permission: Permission.AssetRead })
|
@Authenticated({ permission: Permission.AssetRead })
|
||||||
@ApiOperation({
|
@Endpoint({
|
||||||
summary: 'Retrieve asset OCR data',
|
summary: 'Retrieve asset OCR data',
|
||||||
description: 'Retrieve all OCR (Optical Character Recognition) data associated with the specified asset.',
|
description: 'Retrieve all OCR (Optical Character Recognition) data associated with the specified asset.',
|
||||||
|
history: new HistoryBuilder().added('v1').beta('v1').stable('v2'),
|
||||||
})
|
})
|
||||||
getAssetOcr(@Auth() auth: AuthDto, @Param() { id }: UUIDParamDto): Promise<AssetOcrResponseDto[]> {
|
getAssetOcr(@Auth() auth: AuthDto, @Param() { id }: UUIDParamDto): Promise<AssetOcrResponseDto[]> {
|
||||||
return this.service.getOcr(auth, id);
|
return this.service.getOcr(auth, id);
|
||||||
|
|
@ -150,9 +159,10 @@ export class AssetController {
|
||||||
|
|
||||||
@Put(':id/metadata')
|
@Put(':id/metadata')
|
||||||
@Authenticated({ permission: Permission.AssetUpdate })
|
@Authenticated({ permission: Permission.AssetUpdate })
|
||||||
@ApiOperation({
|
@Endpoint({
|
||||||
summary: 'Update asset metadata',
|
summary: 'Update asset metadata',
|
||||||
description: 'Update or add metadata key-value pairs for the specified asset.',
|
description: 'Update or add metadata key-value pairs for the specified asset.',
|
||||||
|
history: new HistoryBuilder().added('v1').beta('v1').stable('v2'),
|
||||||
})
|
})
|
||||||
updateAssetMetadata(
|
updateAssetMetadata(
|
||||||
@Auth() auth: AuthDto,
|
@Auth() auth: AuthDto,
|
||||||
|
|
@ -164,9 +174,10 @@ export class AssetController {
|
||||||
|
|
||||||
@Get(':id/metadata/:key')
|
@Get(':id/metadata/:key')
|
||||||
@Authenticated({ permission: Permission.AssetRead })
|
@Authenticated({ permission: Permission.AssetRead })
|
||||||
@ApiOperation({
|
@Endpoint({
|
||||||
summary: 'Retrieve asset metadata by key',
|
summary: 'Retrieve asset metadata by key',
|
||||||
description: 'Retrieve the value of a specific metadata key associated with the specified asset.',
|
description: 'Retrieve the value of a specific metadata key associated with the specified asset.',
|
||||||
|
history: new HistoryBuilder().added('v1').beta('v1').stable('v2'),
|
||||||
})
|
})
|
||||||
getAssetMetadataByKey(
|
getAssetMetadataByKey(
|
||||||
@Auth() auth: AuthDto,
|
@Auth() auth: AuthDto,
|
||||||
|
|
@ -178,9 +189,10 @@ export class AssetController {
|
||||||
@Delete(':id/metadata/:key')
|
@Delete(':id/metadata/:key')
|
||||||
@Authenticated({ permission: Permission.AssetUpdate })
|
@Authenticated({ permission: Permission.AssetUpdate })
|
||||||
@HttpCode(HttpStatus.NO_CONTENT)
|
@HttpCode(HttpStatus.NO_CONTENT)
|
||||||
@ApiOperation({
|
@Endpoint({
|
||||||
summary: 'Delete asset metadata by key',
|
summary: 'Delete asset metadata by key',
|
||||||
description: 'Delete a specific metadata key-value pair associated with the specified asset.',
|
description: 'Delete a specific metadata key-value pair associated with the specified asset.',
|
||||||
|
history: new HistoryBuilder().added('v1').beta('v1').stable('v2'),
|
||||||
})
|
})
|
||||||
deleteAssetMetadata(@Auth() auth: AuthDto, @Param() { id, key }: AssetMetadataRouteParams): Promise<void> {
|
deleteAssetMetadata(@Auth() auth: AuthDto, @Param() { id, key }: AssetMetadataRouteParams): Promise<void> {
|
||||||
return this.service.deleteMetadataByKey(auth, id, key);
|
return this.service.deleteMetadataByKey(auth, id, key);
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,6 @@
|
||||||
import { Controller, HttpCode, HttpStatus, Post } from '@nestjs/common';
|
import { Controller, HttpCode, HttpStatus, Post } from '@nestjs/common';
|
||||||
import { ApiOperation, ApiTags } from '@nestjs/swagger';
|
import { ApiTags } from '@nestjs/swagger';
|
||||||
|
import { Endpoint, HistoryBuilder } from 'src/decorators';
|
||||||
import { AuthDto } from 'src/dtos/auth.dto';
|
import { AuthDto } from 'src/dtos/auth.dto';
|
||||||
import { ApiTag, Permission } from 'src/enum';
|
import { ApiTag, Permission } from 'src/enum';
|
||||||
import { Auth, Authenticated } from 'src/middleware/auth.guard';
|
import { Auth, Authenticated } from 'src/middleware/auth.guard';
|
||||||
|
|
@ -12,9 +13,10 @@ export class AuthAdminController {
|
||||||
@Post('unlink-all')
|
@Post('unlink-all')
|
||||||
@Authenticated({ permission: Permission.AdminAuthUnlinkAll, admin: true })
|
@Authenticated({ permission: Permission.AdminAuthUnlinkAll, admin: true })
|
||||||
@HttpCode(HttpStatus.NO_CONTENT)
|
@HttpCode(HttpStatus.NO_CONTENT)
|
||||||
@ApiOperation({
|
@Endpoint({
|
||||||
summary: 'Unlink all OAuth accounts',
|
summary: 'Unlink all OAuth accounts',
|
||||||
description: 'Unlinks all OAuth accounts associated with user accounts in the system.',
|
description: 'Unlinks all OAuth accounts associated with user accounts in the system.',
|
||||||
|
history: new HistoryBuilder().added('v1').beta('v1').stable('v2'),
|
||||||
})
|
})
|
||||||
unlinkAllOAuthAccountsAdmin(@Auth() auth: AuthDto): Promise<void> {
|
unlinkAllOAuthAccountsAdmin(@Auth() auth: AuthDto): Promise<void> {
|
||||||
return this.service.unlinkAll(auth);
|
return this.service.unlinkAll(auth);
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
import { Body, Controller, Delete, Get, HttpCode, HttpStatus, Post, Put, Req, Res } from '@nestjs/common';
|
import { Body, Controller, Delete, Get, HttpCode, HttpStatus, Post, Put, Req, Res } from '@nestjs/common';
|
||||||
import { ApiOperation, ApiTags } from '@nestjs/swagger';
|
import { ApiTags } from '@nestjs/swagger';
|
||||||
import { Request, Response } from 'express';
|
import { Request, Response } from 'express';
|
||||||
|
import { Endpoint, HistoryBuilder } from 'src/decorators';
|
||||||
import {
|
import {
|
||||||
AuthDto,
|
AuthDto,
|
||||||
AuthStatusResponseDto,
|
AuthStatusResponseDto,
|
||||||
|
|
@ -27,9 +28,10 @@ export class AuthController {
|
||||||
constructor(private service: AuthService) {}
|
constructor(private service: AuthService) {}
|
||||||
|
|
||||||
@Post('login')
|
@Post('login')
|
||||||
@ApiOperation({
|
@Endpoint({
|
||||||
summary: 'Login',
|
summary: 'Login',
|
||||||
description: 'Login with username and password and receive a session token.',
|
description: 'Login with username and password and receive a session token.',
|
||||||
|
history: new HistoryBuilder().added('v1').beta('v1').stable('v2'),
|
||||||
})
|
})
|
||||||
async login(
|
async login(
|
||||||
@Res({ passthrough: true }) res: Response,
|
@Res({ passthrough: true }) res: Response,
|
||||||
|
|
@ -48,18 +50,20 @@ export class AuthController {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Post('admin-sign-up')
|
@Post('admin-sign-up')
|
||||||
@ApiOperation({
|
@Endpoint({
|
||||||
summary: 'Register admin',
|
summary: 'Register admin',
|
||||||
description: 'Create the first admin user in the system.',
|
description: 'Create the first admin user in the system.',
|
||||||
|
history: new HistoryBuilder().added('v1').beta('v1').stable('v2'),
|
||||||
})
|
})
|
||||||
signUpAdmin(@Body() dto: SignUpDto): Promise<UserAdminResponseDto> {
|
signUpAdmin(@Body() dto: SignUpDto): Promise<UserAdminResponseDto> {
|
||||||
return this.service.adminSignUp(dto);
|
return this.service.adminSignUp(dto);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Post('validateToken')
|
@Post('validateToken')
|
||||||
@ApiOperation({
|
@Endpoint({
|
||||||
summary: 'Validate access token',
|
summary: 'Validate access token',
|
||||||
description: 'Validate the current authorization method is still valid.',
|
description: 'Validate the current authorization method is still valid.',
|
||||||
|
history: new HistoryBuilder().added('v1').beta('v1').stable('v2'),
|
||||||
})
|
})
|
||||||
@Authenticated({ permission: false })
|
@Authenticated({ permission: false })
|
||||||
@HttpCode(HttpStatus.OK)
|
@HttpCode(HttpStatus.OK)
|
||||||
|
|
@ -70,9 +74,10 @@ export class AuthController {
|
||||||
@Post('change-password')
|
@Post('change-password')
|
||||||
@Authenticated({ permission: Permission.AuthChangePassword })
|
@Authenticated({ permission: Permission.AuthChangePassword })
|
||||||
@HttpCode(HttpStatus.OK)
|
@HttpCode(HttpStatus.OK)
|
||||||
@ApiOperation({
|
@Endpoint({
|
||||||
summary: 'Change password',
|
summary: 'Change password',
|
||||||
description: 'Change the password of the current user.',
|
description: 'Change the password of the current user.',
|
||||||
|
history: new HistoryBuilder().added('v1').beta('v1').stable('v2'),
|
||||||
})
|
})
|
||||||
changePassword(@Auth() auth: AuthDto, @Body() dto: ChangePasswordDto): Promise<UserAdminResponseDto> {
|
changePassword(@Auth() auth: AuthDto, @Body() dto: ChangePasswordDto): Promise<UserAdminResponseDto> {
|
||||||
return this.service.changePassword(auth, dto);
|
return this.service.changePassword(auth, dto);
|
||||||
|
|
@ -81,9 +86,10 @@ export class AuthController {
|
||||||
@Post('logout')
|
@Post('logout')
|
||||||
@Authenticated()
|
@Authenticated()
|
||||||
@HttpCode(HttpStatus.OK)
|
@HttpCode(HttpStatus.OK)
|
||||||
@ApiOperation({
|
@Endpoint({
|
||||||
summary: 'Logout',
|
summary: 'Logout',
|
||||||
description: 'Logout the current user and invalidate the session token.',
|
description: 'Logout the current user and invalidate the session token.',
|
||||||
|
history: new HistoryBuilder().added('v1').beta('v1').stable('v2'),
|
||||||
})
|
})
|
||||||
async logout(
|
async logout(
|
||||||
@Req() request: Request,
|
@Req() request: Request,
|
||||||
|
|
@ -102,7 +108,7 @@ export class AuthController {
|
||||||
|
|
||||||
@Get('status')
|
@Get('status')
|
||||||
@Authenticated()
|
@Authenticated()
|
||||||
@ApiOperation({
|
@Endpoint({
|
||||||
summary: 'Retrieve auth status',
|
summary: 'Retrieve auth status',
|
||||||
description:
|
description:
|
||||||
'Get information about the current session, including whether the user has a password, and if the session can access locked assets.',
|
'Get information about the current session, including whether the user has a password, and if the session can access locked assets.',
|
||||||
|
|
@ -114,9 +120,10 @@ export class AuthController {
|
||||||
@Post('pin-code')
|
@Post('pin-code')
|
||||||
@Authenticated({ permission: Permission.PinCodeCreate })
|
@Authenticated({ permission: Permission.PinCodeCreate })
|
||||||
@HttpCode(HttpStatus.NO_CONTENT)
|
@HttpCode(HttpStatus.NO_CONTENT)
|
||||||
@ApiOperation({
|
@Endpoint({
|
||||||
summary: 'Setup pin code',
|
summary: 'Setup pin code',
|
||||||
description: 'Setup a new pin code for the current user.',
|
description: 'Setup a new pin code for the current user.',
|
||||||
|
history: new HistoryBuilder().added('v1').beta('v1').stable('v2'),
|
||||||
})
|
})
|
||||||
setupPinCode(@Auth() auth: AuthDto, @Body() dto: PinCodeSetupDto): Promise<void> {
|
setupPinCode(@Auth() auth: AuthDto, @Body() dto: PinCodeSetupDto): Promise<void> {
|
||||||
return this.service.setupPinCode(auth, dto);
|
return this.service.setupPinCode(auth, dto);
|
||||||
|
|
@ -125,9 +132,10 @@ export class AuthController {
|
||||||
@Put('pin-code')
|
@Put('pin-code')
|
||||||
@Authenticated({ permission: Permission.PinCodeUpdate })
|
@Authenticated({ permission: Permission.PinCodeUpdate })
|
||||||
@HttpCode(HttpStatus.NO_CONTENT)
|
@HttpCode(HttpStatus.NO_CONTENT)
|
||||||
@ApiOperation({
|
@Endpoint({
|
||||||
summary: 'Change pin code',
|
summary: 'Change pin code',
|
||||||
description: 'Change the pin code for the current user.',
|
description: 'Change the pin code for the current user.',
|
||||||
|
history: new HistoryBuilder().added('v1').beta('v1').stable('v2'),
|
||||||
})
|
})
|
||||||
async changePinCode(@Auth() auth: AuthDto, @Body() dto: PinCodeChangeDto): Promise<void> {
|
async changePinCode(@Auth() auth: AuthDto, @Body() dto: PinCodeChangeDto): Promise<void> {
|
||||||
return this.service.changePinCode(auth, dto);
|
return this.service.changePinCode(auth, dto);
|
||||||
|
|
@ -136,9 +144,10 @@ export class AuthController {
|
||||||
@Delete('pin-code')
|
@Delete('pin-code')
|
||||||
@Authenticated({ permission: Permission.PinCodeDelete })
|
@Authenticated({ permission: Permission.PinCodeDelete })
|
||||||
@HttpCode(HttpStatus.NO_CONTENT)
|
@HttpCode(HttpStatus.NO_CONTENT)
|
||||||
@ApiOperation({
|
@Endpoint({
|
||||||
summary: 'Reset pin code',
|
summary: 'Reset pin code',
|
||||||
description: 'Reset the pin code for the current user by providing the account password',
|
description: 'Reset the pin code for the current user by providing the account password',
|
||||||
|
history: new HistoryBuilder().added('v1').beta('v1').stable('v2'),
|
||||||
})
|
})
|
||||||
async resetPinCode(@Auth() auth: AuthDto, @Body() dto: PinCodeResetDto): Promise<void> {
|
async resetPinCode(@Auth() auth: AuthDto, @Body() dto: PinCodeResetDto): Promise<void> {
|
||||||
return this.service.resetPinCode(auth, dto);
|
return this.service.resetPinCode(auth, dto);
|
||||||
|
|
@ -147,9 +156,10 @@ export class AuthController {
|
||||||
@Post('session/unlock')
|
@Post('session/unlock')
|
||||||
@Authenticated()
|
@Authenticated()
|
||||||
@HttpCode(HttpStatus.NO_CONTENT)
|
@HttpCode(HttpStatus.NO_CONTENT)
|
||||||
@ApiOperation({
|
@Endpoint({
|
||||||
summary: 'Unlock auth session',
|
summary: 'Unlock auth session',
|
||||||
description: 'Temporarily grant the session elevated access to locked assets by providing the correct PIN code.',
|
description: 'Temporarily grant the session elevated access to locked assets by providing the correct PIN code.',
|
||||||
|
history: new HistoryBuilder().added('v1').beta('v1').stable('v2'),
|
||||||
})
|
})
|
||||||
async unlockAuthSession(@Auth() auth: AuthDto, @Body() dto: SessionUnlockDto): Promise<void> {
|
async unlockAuthSession(@Auth() auth: AuthDto, @Body() dto: SessionUnlockDto): Promise<void> {
|
||||||
return this.service.unlockSession(auth, dto);
|
return this.service.unlockSession(auth, dto);
|
||||||
|
|
@ -157,9 +167,10 @@ export class AuthController {
|
||||||
|
|
||||||
@Post('session/lock')
|
@Post('session/lock')
|
||||||
@Authenticated()
|
@Authenticated()
|
||||||
@ApiOperation({
|
@Endpoint({
|
||||||
summary: 'Lock auth session',
|
summary: 'Lock auth session',
|
||||||
description: 'Remove elevated access to locked assets from the current session.',
|
description: 'Remove elevated access to locked assets from the current session.',
|
||||||
|
history: new HistoryBuilder().added('v1').beta('v1').stable('v2'),
|
||||||
})
|
})
|
||||||
@HttpCode(HttpStatus.NO_CONTENT)
|
@HttpCode(HttpStatus.NO_CONTENT)
|
||||||
async lockAuthSession(@Auth() auth: AuthDto): Promise<void> {
|
async lockAuthSession(@Auth() auth: AuthDto): Promise<void> {
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,6 @@
|
||||||
import { Body, Controller, HttpCode, HttpStatus, Post, StreamableFile } from '@nestjs/common';
|
import { Body, Controller, HttpCode, HttpStatus, Post, StreamableFile } from '@nestjs/common';
|
||||||
import { ApiOperation, ApiTags } from '@nestjs/swagger';
|
import { ApiTags } from '@nestjs/swagger';
|
||||||
|
import { Endpoint, HistoryBuilder } from 'src/decorators';
|
||||||
import { AssetIdsDto } from 'src/dtos/asset.dto';
|
import { AssetIdsDto } from 'src/dtos/asset.dto';
|
||||||
import { AuthDto } from 'src/dtos/auth.dto';
|
import { AuthDto } from 'src/dtos/auth.dto';
|
||||||
import { DownloadInfoDto, DownloadResponseDto } from 'src/dtos/download.dto';
|
import { DownloadInfoDto, DownloadResponseDto } from 'src/dtos/download.dto';
|
||||||
|
|
@ -15,10 +16,11 @@ export class DownloadController {
|
||||||
|
|
||||||
@Post('info')
|
@Post('info')
|
||||||
@Authenticated({ permission: Permission.AssetDownload, sharedLink: true })
|
@Authenticated({ permission: Permission.AssetDownload, sharedLink: true })
|
||||||
@ApiOperation({
|
@Endpoint({
|
||||||
summary: 'Retrieve download information',
|
summary: 'Retrieve download information',
|
||||||
description:
|
description:
|
||||||
'Retrieve information about how to request a download for the specified assets or album. The response includes groups of assets that can be downloaded together.',
|
'Retrieve information about how to request a download for the specified assets or album. The response includes groups of assets that can be downloaded together.',
|
||||||
|
history: new HistoryBuilder().added('v1').beta('v1').stable('v2'),
|
||||||
})
|
})
|
||||||
getDownloadInfo(@Auth() auth: AuthDto, @Body() dto: DownloadInfoDto): Promise<DownloadResponseDto> {
|
getDownloadInfo(@Auth() auth: AuthDto, @Body() dto: DownloadInfoDto): Promise<DownloadResponseDto> {
|
||||||
return this.service.getDownloadInfo(auth, dto);
|
return this.service.getDownloadInfo(auth, dto);
|
||||||
|
|
@ -28,10 +30,11 @@ export class DownloadController {
|
||||||
@Authenticated({ permission: Permission.AssetDownload, sharedLink: true })
|
@Authenticated({ permission: Permission.AssetDownload, sharedLink: true })
|
||||||
@FileResponse()
|
@FileResponse()
|
||||||
@HttpCode(HttpStatus.OK)
|
@HttpCode(HttpStatus.OK)
|
||||||
@ApiOperation({
|
@Endpoint({
|
||||||
summary: 'Download asset archive',
|
summary: 'Download asset archive',
|
||||||
description:
|
description:
|
||||||
'Download a ZIP archive containing the specified assets. The assets must have been previously requested via the "getDownloadInfo" endpoint.',
|
'Download a ZIP archive containing the specified assets. The assets must have been previously requested via the "getDownloadInfo" endpoint.',
|
||||||
|
history: new HistoryBuilder().added('v1').beta('v1').stable('v2'),
|
||||||
})
|
})
|
||||||
downloadArchive(@Auth() auth: AuthDto, @Body() dto: AssetIdsDto): Promise<StreamableFile> {
|
downloadArchive(@Auth() auth: AuthDto, @Body() dto: AssetIdsDto): Promise<StreamableFile> {
|
||||||
return this.service.downloadArchive(auth, dto).then(asStreamableFile);
|
return this.service.downloadArchive(auth, dto).then(asStreamableFile);
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,6 @@
|
||||||
import { Body, Controller, Delete, Get, HttpCode, HttpStatus, Param } from '@nestjs/common';
|
import { Body, Controller, Delete, Get, HttpCode, HttpStatus, Param } from '@nestjs/common';
|
||||||
import { ApiOperation, ApiTags } from '@nestjs/swagger';
|
import { ApiTags } from '@nestjs/swagger';
|
||||||
|
import { Endpoint, HistoryBuilder } from 'src/decorators';
|
||||||
import { BulkIdsDto } from 'src/dtos/asset-ids.response.dto';
|
import { BulkIdsDto } from 'src/dtos/asset-ids.response.dto';
|
||||||
import { AuthDto } from 'src/dtos/auth.dto';
|
import { AuthDto } from 'src/dtos/auth.dto';
|
||||||
import { DuplicateResponseDto } from 'src/dtos/duplicate.dto';
|
import { DuplicateResponseDto } from 'src/dtos/duplicate.dto';
|
||||||
|
|
@ -15,9 +16,10 @@ export class DuplicateController {
|
||||||
|
|
||||||
@Get()
|
@Get()
|
||||||
@Authenticated({ permission: Permission.DuplicateRead })
|
@Authenticated({ permission: Permission.DuplicateRead })
|
||||||
@ApiOperation({
|
@Endpoint({
|
||||||
summary: 'Retrieve duplicates',
|
summary: 'Retrieve duplicates',
|
||||||
description: 'Retrieve a list of duplicate assets available to the authenticated user.',
|
description: 'Retrieve a list of duplicate assets available to the authenticated user.',
|
||||||
|
history: new HistoryBuilder().added('v1').beta('v1').stable('v2'),
|
||||||
})
|
})
|
||||||
getAssetDuplicates(@Auth() auth: AuthDto): Promise<DuplicateResponseDto[]> {
|
getAssetDuplicates(@Auth() auth: AuthDto): Promise<DuplicateResponseDto[]> {
|
||||||
return this.service.getDuplicates(auth);
|
return this.service.getDuplicates(auth);
|
||||||
|
|
@ -26,9 +28,10 @@ export class DuplicateController {
|
||||||
@Delete()
|
@Delete()
|
||||||
@Authenticated({ permission: Permission.DuplicateDelete })
|
@Authenticated({ permission: Permission.DuplicateDelete })
|
||||||
@HttpCode(HttpStatus.NO_CONTENT)
|
@HttpCode(HttpStatus.NO_CONTENT)
|
||||||
@ApiOperation({
|
@Endpoint({
|
||||||
summary: 'Delete duplicates',
|
summary: 'Delete duplicates',
|
||||||
description: 'Delete multiple duplicate assets specified by their IDs.',
|
description: 'Delete multiple duplicate assets specified by their IDs.',
|
||||||
|
history: new HistoryBuilder().added('v1').beta('v1').stable('v2'),
|
||||||
})
|
})
|
||||||
deleteDuplicates(@Auth() auth: AuthDto, @Body() dto: BulkIdsDto): Promise<void> {
|
deleteDuplicates(@Auth() auth: AuthDto, @Body() dto: BulkIdsDto): Promise<void> {
|
||||||
return this.service.deleteAll(auth, dto);
|
return this.service.deleteAll(auth, dto);
|
||||||
|
|
@ -37,9 +40,10 @@ export class DuplicateController {
|
||||||
@Delete(':id')
|
@Delete(':id')
|
||||||
@Authenticated({ permission: Permission.DuplicateDelete })
|
@Authenticated({ permission: Permission.DuplicateDelete })
|
||||||
@HttpCode(HttpStatus.NO_CONTENT)
|
@HttpCode(HttpStatus.NO_CONTENT)
|
||||||
@ApiOperation({
|
@Endpoint({
|
||||||
summary: 'Delete a duplicate',
|
summary: 'Delete a duplicate',
|
||||||
description: 'Delete a single duplicate asset specified by its ID.',
|
description: 'Delete a single duplicate asset specified by its ID.',
|
||||||
|
history: new HistoryBuilder().added('v1').beta('v1').stable('v2'),
|
||||||
})
|
})
|
||||||
deleteDuplicate(@Auth() auth: AuthDto, @Param() { id }: UUIDParamDto): Promise<void> {
|
deleteDuplicate(@Auth() auth: AuthDto, @Param() { id }: UUIDParamDto): Promise<void> {
|
||||||
return this.service.delete(auth, id);
|
return this.service.delete(auth, id);
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,6 @@
|
||||||
import { Body, Controller, Delete, Get, HttpCode, HttpStatus, Param, Post, Put, Query } from '@nestjs/common';
|
import { Body, Controller, Delete, Get, HttpCode, HttpStatus, Param, Post, Put, Query } from '@nestjs/common';
|
||||||
import { ApiOperation, ApiTags } from '@nestjs/swagger';
|
import { ApiTags } from '@nestjs/swagger';
|
||||||
|
import { Endpoint, HistoryBuilder } from 'src/decorators';
|
||||||
import { AuthDto } from 'src/dtos/auth.dto';
|
import { AuthDto } from 'src/dtos/auth.dto';
|
||||||
import {
|
import {
|
||||||
AssetFaceCreateDto,
|
AssetFaceCreateDto,
|
||||||
|
|
@ -20,10 +21,11 @@ export class FaceController {
|
||||||
|
|
||||||
@Post()
|
@Post()
|
||||||
@Authenticated({ permission: Permission.FaceCreate })
|
@Authenticated({ permission: Permission.FaceCreate })
|
||||||
@ApiOperation({
|
@Endpoint({
|
||||||
summary: 'Create a face',
|
summary: 'Create a face',
|
||||||
description:
|
description:
|
||||||
'Create a new face that has not been discovered by facial recognition. The content of the bounding box is considered a face.',
|
'Create a new face that has not been discovered by facial recognition. The content of the bounding box is considered a face.',
|
||||||
|
history: new HistoryBuilder().added('v1').beta('v1').stable('v2'),
|
||||||
})
|
})
|
||||||
createFace(@Auth() auth: AuthDto, @Body() dto: AssetFaceCreateDto) {
|
createFace(@Auth() auth: AuthDto, @Body() dto: AssetFaceCreateDto) {
|
||||||
return this.service.createFace(auth, dto);
|
return this.service.createFace(auth, dto);
|
||||||
|
|
@ -31,9 +33,10 @@ export class FaceController {
|
||||||
|
|
||||||
@Get()
|
@Get()
|
||||||
@Authenticated({ permission: Permission.FaceRead })
|
@Authenticated({ permission: Permission.FaceRead })
|
||||||
@ApiOperation({
|
@Endpoint({
|
||||||
summary: 'Retrieve faces for asset',
|
summary: 'Retrieve faces for asset',
|
||||||
description: 'Retrieve all faces belonging to an asset.',
|
description: 'Retrieve all faces belonging to an asset.',
|
||||||
|
history: new HistoryBuilder().added('v1').beta('v1').stable('v2'),
|
||||||
})
|
})
|
||||||
getFaces(@Auth() auth: AuthDto, @Query() dto: FaceDto): Promise<AssetFaceResponseDto[]> {
|
getFaces(@Auth() auth: AuthDto, @Query() dto: FaceDto): Promise<AssetFaceResponseDto[]> {
|
||||||
return this.service.getFacesById(auth, dto);
|
return this.service.getFacesById(auth, dto);
|
||||||
|
|
@ -41,9 +44,10 @@ export class FaceController {
|
||||||
|
|
||||||
@Put(':id')
|
@Put(':id')
|
||||||
@Authenticated({ permission: Permission.FaceUpdate })
|
@Authenticated({ permission: Permission.FaceUpdate })
|
||||||
@ApiOperation({
|
@Endpoint({
|
||||||
summary: 'Re-assign a face to another person',
|
summary: 'Re-assign a face to another person',
|
||||||
description: 'Re-assign the face provided in the body to the person identified by the id in the path parameter.',
|
description: 'Re-assign the face provided in the body to the person identified by the id in the path parameter.',
|
||||||
|
history: new HistoryBuilder().added('v1').beta('v1').stable('v2'),
|
||||||
})
|
})
|
||||||
reassignFacesById(
|
reassignFacesById(
|
||||||
@Auth() auth: AuthDto,
|
@Auth() auth: AuthDto,
|
||||||
|
|
@ -56,9 +60,10 @@ export class FaceController {
|
||||||
@Delete(':id')
|
@Delete(':id')
|
||||||
@Authenticated({ permission: Permission.FaceDelete })
|
@Authenticated({ permission: Permission.FaceDelete })
|
||||||
@HttpCode(HttpStatus.NO_CONTENT)
|
@HttpCode(HttpStatus.NO_CONTENT)
|
||||||
@ApiOperation({
|
@Endpoint({
|
||||||
summary: 'Delete a face',
|
summary: 'Delete a face',
|
||||||
description: 'Delete a face identified by the id. Optionally can be force deleted.',
|
description: 'Delete a face identified by the id. Optionally can be force deleted.',
|
||||||
|
history: new HistoryBuilder().added('v1').beta('v1').stable('v2'),
|
||||||
})
|
})
|
||||||
deleteFace(@Auth() auth: AuthDto, @Param() { id }: UUIDParamDto, @Body() dto: AssetFaceDeleteDto): Promise<void> {
|
deleteFace(@Auth() auth: AuthDto, @Param() { id }: UUIDParamDto, @Body() dto: AssetFaceDeleteDto): Promise<void> {
|
||||||
return this.service.deleteFace(auth, id, dto);
|
return this.service.deleteFace(auth, id, dto);
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,6 @@
|
||||||
import { Body, Controller, Get, HttpCode, HttpStatus, Param, Post, Put } from '@nestjs/common';
|
import { Body, Controller, Get, HttpCode, HttpStatus, Param, Post, Put } from '@nestjs/common';
|
||||||
import { ApiOperation, ApiTags } from '@nestjs/swagger';
|
import { ApiTags } from '@nestjs/swagger';
|
||||||
|
import { Endpoint, HistoryBuilder } from 'src/decorators';
|
||||||
import { AllJobStatusResponseDto, JobCommandDto, JobCreateDto, JobIdParamDto, JobStatusDto } from 'src/dtos/job.dto';
|
import { AllJobStatusResponseDto, JobCommandDto, JobCreateDto, JobIdParamDto, JobStatusDto } from 'src/dtos/job.dto';
|
||||||
import { ApiTag, Permission } from 'src/enum';
|
import { ApiTag, Permission } from 'src/enum';
|
||||||
import { Authenticated } from 'src/middleware/auth.guard';
|
import { Authenticated } from 'src/middleware/auth.guard';
|
||||||
|
|
@ -12,9 +13,10 @@ export class JobController {
|
||||||
|
|
||||||
@Get()
|
@Get()
|
||||||
@Authenticated({ permission: Permission.JobRead, admin: true })
|
@Authenticated({ permission: Permission.JobRead, admin: true })
|
||||||
@ApiOperation({
|
@Endpoint({
|
||||||
summary: 'Retrieve queue counts and status',
|
summary: 'Retrieve queue counts and status',
|
||||||
description: 'Retrieve the counts of the current queue, as well as the current status.',
|
description: 'Retrieve the counts of the current queue, as well as the current status.',
|
||||||
|
history: new HistoryBuilder().added('v1').beta('v1').stable('v2'),
|
||||||
})
|
})
|
||||||
getAllJobsStatus(): Promise<AllJobStatusResponseDto> {
|
getAllJobsStatus(): Promise<AllJobStatusResponseDto> {
|
||||||
return this.service.getAllJobsStatus();
|
return this.service.getAllJobsStatus();
|
||||||
|
|
@ -23,10 +25,11 @@ export class JobController {
|
||||||
@Post()
|
@Post()
|
||||||
@Authenticated({ permission: Permission.JobCreate, admin: true })
|
@Authenticated({ permission: Permission.JobCreate, admin: true })
|
||||||
@HttpCode(HttpStatus.NO_CONTENT)
|
@HttpCode(HttpStatus.NO_CONTENT)
|
||||||
@ApiOperation({
|
@Endpoint({
|
||||||
summary: 'Create a manual job',
|
summary: 'Create a manual job',
|
||||||
description:
|
description:
|
||||||
'Run a specific job. Most jobs are queued automatically, but this endpoint allows for manual creation of a handful of jobs, including various cleanup tasks, as well as creating a new database backup.',
|
'Run a specific job. Most jobs are queued automatically, but this endpoint allows for manual creation of a handful of jobs, including various cleanup tasks, as well as creating a new database backup.',
|
||||||
|
history: new HistoryBuilder().added('v1').beta('v1').stable('v2'),
|
||||||
})
|
})
|
||||||
createJob(@Body() dto: JobCreateDto): Promise<void> {
|
createJob(@Body() dto: JobCreateDto): Promise<void> {
|
||||||
return this.service.create(dto);
|
return this.service.create(dto);
|
||||||
|
|
@ -34,10 +37,11 @@ export class JobController {
|
||||||
|
|
||||||
@Put(':id')
|
@Put(':id')
|
||||||
@Authenticated({ permission: Permission.JobCreate, admin: true })
|
@Authenticated({ permission: Permission.JobCreate, admin: true })
|
||||||
@ApiOperation({
|
@Endpoint({
|
||||||
summary: 'Run jobs',
|
summary: 'Run jobs',
|
||||||
description:
|
description:
|
||||||
'Queue all assets for a specific job type. Defaults to only queueing assets that have not yet been processed, but the force command can be used to re-process all assets.',
|
'Queue all assets for a specific job type. Defaults to only queueing assets that have not yet been processed, but the force command can be used to re-process all assets.',
|
||||||
|
history: new HistoryBuilder().added('v1').beta('v1').stable('v2'),
|
||||||
})
|
})
|
||||||
sendJobCommand(@Param() { id }: JobIdParamDto, @Body() dto: JobCommandDto): Promise<JobStatusDto> {
|
sendJobCommand(@Param() { id }: JobIdParamDto, @Body() dto: JobCommandDto): Promise<JobStatusDto> {
|
||||||
return this.service.handleCommand(id, dto);
|
return this.service.handleCommand(id, dto);
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,6 @@
|
||||||
import { Body, Controller, Delete, Get, HttpCode, HttpStatus, Param, Post, Put } from '@nestjs/common';
|
import { Body, Controller, Delete, Get, HttpCode, HttpStatus, Param, Post, Put } from '@nestjs/common';
|
||||||
import { ApiOperation, ApiTags } from '@nestjs/swagger';
|
import { ApiTags } from '@nestjs/swagger';
|
||||||
|
import { Endpoint, HistoryBuilder } from 'src/decorators';
|
||||||
import {
|
import {
|
||||||
CreateLibraryDto,
|
CreateLibraryDto,
|
||||||
LibraryResponseDto,
|
LibraryResponseDto,
|
||||||
|
|
@ -20,9 +21,10 @@ export class LibraryController {
|
||||||
|
|
||||||
@Get()
|
@Get()
|
||||||
@Authenticated({ permission: Permission.LibraryRead, admin: true })
|
@Authenticated({ permission: Permission.LibraryRead, admin: true })
|
||||||
@ApiOperation({
|
@Endpoint({
|
||||||
summary: 'Retrieve libraries',
|
summary: 'Retrieve libraries',
|
||||||
description: 'Retrieve a list of external libraries.',
|
description: 'Retrieve a list of external libraries.',
|
||||||
|
history: new HistoryBuilder().added('v1').beta('v1').stable('v2'),
|
||||||
})
|
})
|
||||||
getAllLibraries(): Promise<LibraryResponseDto[]> {
|
getAllLibraries(): Promise<LibraryResponseDto[]> {
|
||||||
return this.service.getAll();
|
return this.service.getAll();
|
||||||
|
|
@ -30,9 +32,10 @@ export class LibraryController {
|
||||||
|
|
||||||
@Post()
|
@Post()
|
||||||
@Authenticated({ permission: Permission.LibraryCreate, admin: true })
|
@Authenticated({ permission: Permission.LibraryCreate, admin: true })
|
||||||
@ApiOperation({
|
@Endpoint({
|
||||||
summary: 'Create a library',
|
summary: 'Create a library',
|
||||||
description: 'Create a new external library.',
|
description: 'Create a new external library.',
|
||||||
|
history: new HistoryBuilder().added('v1').beta('v1').stable('v2'),
|
||||||
})
|
})
|
||||||
createLibrary(@Body() dto: CreateLibraryDto): Promise<LibraryResponseDto> {
|
createLibrary(@Body() dto: CreateLibraryDto): Promise<LibraryResponseDto> {
|
||||||
return this.service.create(dto);
|
return this.service.create(dto);
|
||||||
|
|
@ -40,9 +43,10 @@ export class LibraryController {
|
||||||
|
|
||||||
@Get(':id')
|
@Get(':id')
|
||||||
@Authenticated({ permission: Permission.LibraryRead, admin: true })
|
@Authenticated({ permission: Permission.LibraryRead, admin: true })
|
||||||
@ApiOperation({
|
@Endpoint({
|
||||||
summary: 'Retrieve a library',
|
summary: 'Retrieve a library',
|
||||||
description: 'Retrieve an external library by its ID.',
|
description: 'Retrieve an external library by its ID.',
|
||||||
|
history: new HistoryBuilder().added('v1').beta('v1').stable('v2'),
|
||||||
})
|
})
|
||||||
getLibrary(@Param() { id }: UUIDParamDto): Promise<LibraryResponseDto> {
|
getLibrary(@Param() { id }: UUIDParamDto): Promise<LibraryResponseDto> {
|
||||||
return this.service.get(id);
|
return this.service.get(id);
|
||||||
|
|
@ -50,9 +54,10 @@ export class LibraryController {
|
||||||
|
|
||||||
@Put(':id')
|
@Put(':id')
|
||||||
@Authenticated({ permission: Permission.LibraryUpdate, admin: true })
|
@Authenticated({ permission: Permission.LibraryUpdate, admin: true })
|
||||||
@ApiOperation({
|
@Endpoint({
|
||||||
summary: 'Update a library',
|
summary: 'Update a library',
|
||||||
description: 'Update an existing external library.',
|
description: 'Update an existing external library.',
|
||||||
|
history: new HistoryBuilder().added('v1').beta('v1').stable('v2'),
|
||||||
})
|
})
|
||||||
updateLibrary(@Param() { id }: UUIDParamDto, @Body() dto: UpdateLibraryDto): Promise<LibraryResponseDto> {
|
updateLibrary(@Param() { id }: UUIDParamDto, @Body() dto: UpdateLibraryDto): Promise<LibraryResponseDto> {
|
||||||
return this.service.update(id, dto);
|
return this.service.update(id, dto);
|
||||||
|
|
@ -61,9 +66,10 @@ export class LibraryController {
|
||||||
@Delete(':id')
|
@Delete(':id')
|
||||||
@Authenticated({ permission: Permission.LibraryDelete, admin: true })
|
@Authenticated({ permission: Permission.LibraryDelete, admin: true })
|
||||||
@HttpCode(HttpStatus.NO_CONTENT)
|
@HttpCode(HttpStatus.NO_CONTENT)
|
||||||
@ApiOperation({
|
@Endpoint({
|
||||||
summary: 'Delete a library',
|
summary: 'Delete a library',
|
||||||
description: 'Delete an external library by its ID.',
|
description: 'Delete an external library by its ID.',
|
||||||
|
history: new HistoryBuilder().added('v1').beta('v1').stable('v2'),
|
||||||
})
|
})
|
||||||
deleteLibrary(@Param() { id }: UUIDParamDto): Promise<void> {
|
deleteLibrary(@Param() { id }: UUIDParamDto): Promise<void> {
|
||||||
return this.service.delete(id);
|
return this.service.delete(id);
|
||||||
|
|
@ -72,9 +78,10 @@ export class LibraryController {
|
||||||
@Post(':id/validate')
|
@Post(':id/validate')
|
||||||
@Authenticated({ admin: true })
|
@Authenticated({ admin: true })
|
||||||
@HttpCode(HttpStatus.OK)
|
@HttpCode(HttpStatus.OK)
|
||||||
@ApiOperation({
|
@Endpoint({
|
||||||
summary: 'Validate library settings',
|
summary: 'Validate library settings',
|
||||||
description: 'Validate the settings of an external library.',
|
description: 'Validate the settings of an external library.',
|
||||||
|
history: new HistoryBuilder().added('v1').beta('v1').stable('v2'),
|
||||||
})
|
})
|
||||||
// TODO: change endpoint to validate current settings instead
|
// TODO: change endpoint to validate current settings instead
|
||||||
validate(@Param() { id }: UUIDParamDto, @Body() dto: ValidateLibraryDto): Promise<ValidateLibraryResponseDto> {
|
validate(@Param() { id }: UUIDParamDto, @Body() dto: ValidateLibraryDto): Promise<ValidateLibraryResponseDto> {
|
||||||
|
|
@ -83,10 +90,11 @@ export class LibraryController {
|
||||||
|
|
||||||
@Get(':id/statistics')
|
@Get(':id/statistics')
|
||||||
@Authenticated({ permission: Permission.LibraryStatistics, admin: true })
|
@Authenticated({ permission: Permission.LibraryStatistics, admin: true })
|
||||||
@ApiOperation({
|
@Endpoint({
|
||||||
summary: 'Retrieve library statistics',
|
summary: 'Retrieve library statistics',
|
||||||
description:
|
description:
|
||||||
'Retrieve statistics for a specific external library, including number of videos, images, and storage usage.',
|
'Retrieve statistics for a specific external library, including number of videos, images, and storage usage.',
|
||||||
|
history: new HistoryBuilder().added('v1').beta('v1').stable('v2'),
|
||||||
})
|
})
|
||||||
getLibraryStatistics(@Param() { id }: UUIDParamDto): Promise<LibraryStatsResponseDto> {
|
getLibraryStatistics(@Param() { id }: UUIDParamDto): Promise<LibraryStatsResponseDto> {
|
||||||
return this.service.getStatistics(id);
|
return this.service.getStatistics(id);
|
||||||
|
|
@ -95,9 +103,10 @@ export class LibraryController {
|
||||||
@Post(':id/scan')
|
@Post(':id/scan')
|
||||||
@Authenticated({ permission: Permission.LibraryUpdate, admin: true })
|
@Authenticated({ permission: Permission.LibraryUpdate, admin: true })
|
||||||
@HttpCode(HttpStatus.NO_CONTENT)
|
@HttpCode(HttpStatus.NO_CONTENT)
|
||||||
@ApiOperation({
|
@Endpoint({
|
||||||
summary: 'Scan a library',
|
summary: 'Scan a library',
|
||||||
description: 'Queue a scan for the external library to find and import new assets.',
|
description: 'Queue a scan for the external library to find and import new assets.',
|
||||||
|
history: new HistoryBuilder().added('v1').beta('v1').stable('v2'),
|
||||||
})
|
})
|
||||||
scanLibrary(@Param() { id }: UUIDParamDto): Promise<void> {
|
scanLibrary(@Param() { id }: UUIDParamDto): Promise<void> {
|
||||||
return this.service.queueScan(id);
|
return this.service.queueScan(id);
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,6 @@
|
||||||
import { Controller, Get, HttpCode, HttpStatus, Query } from '@nestjs/common';
|
import { Controller, Get, HttpCode, HttpStatus, Query } from '@nestjs/common';
|
||||||
import { ApiOperation, ApiTags } from '@nestjs/swagger';
|
import { ApiTags } from '@nestjs/swagger';
|
||||||
|
import { Endpoint, HistoryBuilder } from 'src/decorators';
|
||||||
import { AuthDto } from 'src/dtos/auth.dto';
|
import { AuthDto } from 'src/dtos/auth.dto';
|
||||||
import {
|
import {
|
||||||
MapMarkerDto,
|
MapMarkerDto,
|
||||||
|
|
@ -18,9 +19,10 @@ export class MapController {
|
||||||
|
|
||||||
@Get('markers')
|
@Get('markers')
|
||||||
@Authenticated()
|
@Authenticated()
|
||||||
@ApiOperation({
|
@Endpoint({
|
||||||
summary: 'Retrieve map markers',
|
summary: 'Retrieve map markers',
|
||||||
description: 'Retrieve a list of latitude and longitude coordinates for every asset with location data.',
|
description: 'Retrieve a list of latitude and longitude coordinates for every asset with location data.',
|
||||||
|
history: new HistoryBuilder().added('v1').beta('v1').stable('v2'),
|
||||||
})
|
})
|
||||||
getMapMarkers(@Auth() auth: AuthDto, @Query() options: MapMarkerDto): Promise<MapMarkerResponseDto[]> {
|
getMapMarkers(@Auth() auth: AuthDto, @Query() options: MapMarkerDto): Promise<MapMarkerResponseDto[]> {
|
||||||
return this.service.getMapMarkers(auth, options);
|
return this.service.getMapMarkers(auth, options);
|
||||||
|
|
@ -29,9 +31,10 @@ export class MapController {
|
||||||
@Authenticated()
|
@Authenticated()
|
||||||
@Get('reverse-geocode')
|
@Get('reverse-geocode')
|
||||||
@HttpCode(HttpStatus.OK)
|
@HttpCode(HttpStatus.OK)
|
||||||
@ApiOperation({
|
@Endpoint({
|
||||||
summary: 'Reverse geocode coordinates',
|
summary: 'Reverse geocode coordinates',
|
||||||
description: 'Retrieve location information (e.g., city, country) for given latitude and longitude coordinates.',
|
description: 'Retrieve location information (e.g., city, country) for given latitude and longitude coordinates.',
|
||||||
|
history: new HistoryBuilder().added('v1').beta('v1').stable('v2'),
|
||||||
})
|
})
|
||||||
reverseGeocode(@Query() dto: MapReverseGeocodeDto): Promise<MapReverseGeocodeResponseDto[]> {
|
reverseGeocode(@Query() dto: MapReverseGeocodeDto): Promise<MapReverseGeocodeResponseDto[]> {
|
||||||
return this.service.reverseGeocode(dto);
|
return this.service.reverseGeocode(dto);
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,6 @@
|
||||||
import { Body, Controller, Delete, Get, HttpCode, HttpStatus, Param, Post, Put, Query } from '@nestjs/common';
|
import { Body, Controller, Delete, Get, HttpCode, HttpStatus, Param, Post, Put, Query } from '@nestjs/common';
|
||||||
import { ApiOperation, ApiTags } from '@nestjs/swagger';
|
import { ApiTags } from '@nestjs/swagger';
|
||||||
|
import { Endpoint, HistoryBuilder } from 'src/decorators';
|
||||||
import { BulkIdResponseDto, BulkIdsDto } from 'src/dtos/asset-ids.response.dto';
|
import { BulkIdResponseDto, BulkIdsDto } from 'src/dtos/asset-ids.response.dto';
|
||||||
import { AuthDto } from 'src/dtos/auth.dto';
|
import { AuthDto } from 'src/dtos/auth.dto';
|
||||||
import {
|
import {
|
||||||
|
|
@ -21,10 +22,11 @@ export class MemoryController {
|
||||||
|
|
||||||
@Get()
|
@Get()
|
||||||
@Authenticated({ permission: Permission.MemoryRead })
|
@Authenticated({ permission: Permission.MemoryRead })
|
||||||
@ApiOperation({
|
@Endpoint({
|
||||||
summary: 'Retrieve memories',
|
summary: 'Retrieve memories',
|
||||||
description:
|
description:
|
||||||
'Retrieve a list of memories. Memories are sorted descending by creation date by default, although they can also be sorted in ascending order, or randomly.',
|
'Retrieve a list of memories. Memories are sorted descending by creation date by default, although they can also be sorted in ascending order, or randomly.',
|
||||||
|
history: new HistoryBuilder().added('v1').beta('v1').stable('v2'),
|
||||||
})
|
})
|
||||||
searchMemories(@Auth() auth: AuthDto, @Query() dto: MemorySearchDto): Promise<MemoryResponseDto[]> {
|
searchMemories(@Auth() auth: AuthDto, @Query() dto: MemorySearchDto): Promise<MemoryResponseDto[]> {
|
||||||
return this.service.search(auth, dto);
|
return this.service.search(auth, dto);
|
||||||
|
|
@ -32,10 +34,11 @@ export class MemoryController {
|
||||||
|
|
||||||
@Post()
|
@Post()
|
||||||
@Authenticated({ permission: Permission.MemoryCreate })
|
@Authenticated({ permission: Permission.MemoryCreate })
|
||||||
@ApiOperation({
|
@Endpoint({
|
||||||
summary: 'Create a memory',
|
summary: 'Create a memory',
|
||||||
description:
|
description:
|
||||||
'Create a new memory by providing a name, description, and a list of asset IDs to include in the memory.',
|
'Create a new memory by providing a name, description, and a list of asset IDs to include in the memory.',
|
||||||
|
history: new HistoryBuilder().added('v1').beta('v1').stable('v2'),
|
||||||
})
|
})
|
||||||
createMemory(@Auth() auth: AuthDto, @Body() dto: MemoryCreateDto): Promise<MemoryResponseDto> {
|
createMemory(@Auth() auth: AuthDto, @Body() dto: MemoryCreateDto): Promise<MemoryResponseDto> {
|
||||||
return this.service.create(auth, dto);
|
return this.service.create(auth, dto);
|
||||||
|
|
@ -43,9 +46,10 @@ export class MemoryController {
|
||||||
|
|
||||||
@Get('statistics')
|
@Get('statistics')
|
||||||
@Authenticated({ permission: Permission.MemoryStatistics })
|
@Authenticated({ permission: Permission.MemoryStatistics })
|
||||||
@ApiOperation({
|
@Endpoint({
|
||||||
summary: 'Retrieve memories statistics',
|
summary: 'Retrieve memories statistics',
|
||||||
description: 'Retrieve statistics about memories, such as total count and other relevant metrics.',
|
description: 'Retrieve statistics about memories, such as total count and other relevant metrics.',
|
||||||
|
history: new HistoryBuilder().added('v1').beta('v1').stable('v2'),
|
||||||
})
|
})
|
||||||
memoriesStatistics(@Auth() auth: AuthDto, @Query() dto: MemorySearchDto): Promise<MemoryStatisticsResponseDto> {
|
memoriesStatistics(@Auth() auth: AuthDto, @Query() dto: MemorySearchDto): Promise<MemoryStatisticsResponseDto> {
|
||||||
return this.service.statistics(auth, dto);
|
return this.service.statistics(auth, dto);
|
||||||
|
|
@ -53,9 +57,10 @@ export class MemoryController {
|
||||||
|
|
||||||
@Get(':id')
|
@Get(':id')
|
||||||
@Authenticated({ permission: Permission.MemoryRead })
|
@Authenticated({ permission: Permission.MemoryRead })
|
||||||
@ApiOperation({
|
@Endpoint({
|
||||||
summary: 'Retrieve a memory',
|
summary: 'Retrieve a memory',
|
||||||
description: 'Retrieve a specific memory by its ID.',
|
description: 'Retrieve a specific memory by its ID.',
|
||||||
|
history: new HistoryBuilder().added('v1').beta('v1').stable('v2'),
|
||||||
})
|
})
|
||||||
getMemory(@Auth() auth: AuthDto, @Param() { id }: UUIDParamDto): Promise<MemoryResponseDto> {
|
getMemory(@Auth() auth: AuthDto, @Param() { id }: UUIDParamDto): Promise<MemoryResponseDto> {
|
||||||
return this.service.get(auth, id);
|
return this.service.get(auth, id);
|
||||||
|
|
@ -63,9 +68,10 @@ export class MemoryController {
|
||||||
|
|
||||||
@Put(':id')
|
@Put(':id')
|
||||||
@Authenticated({ permission: Permission.MemoryUpdate })
|
@Authenticated({ permission: Permission.MemoryUpdate })
|
||||||
@ApiOperation({
|
@Endpoint({
|
||||||
summary: 'Update a memory',
|
summary: 'Update a memory',
|
||||||
description: 'Update an existing memory by its ID.',
|
description: 'Update an existing memory by its ID.',
|
||||||
|
history: new HistoryBuilder().added('v1').beta('v1').stable('v2'),
|
||||||
})
|
})
|
||||||
updateMemory(
|
updateMemory(
|
||||||
@Auth() auth: AuthDto,
|
@Auth() auth: AuthDto,
|
||||||
|
|
@ -78,9 +84,10 @@ export class MemoryController {
|
||||||
@Delete(':id')
|
@Delete(':id')
|
||||||
@Authenticated({ permission: Permission.MemoryDelete })
|
@Authenticated({ permission: Permission.MemoryDelete })
|
||||||
@HttpCode(HttpStatus.NO_CONTENT)
|
@HttpCode(HttpStatus.NO_CONTENT)
|
||||||
@ApiOperation({
|
@Endpoint({
|
||||||
summary: 'Delete a memory',
|
summary: 'Delete a memory',
|
||||||
description: 'Delete a specific memory by its ID.',
|
description: 'Delete a specific memory by its ID.',
|
||||||
|
history: new HistoryBuilder().added('v1').beta('v1').stable('v2'),
|
||||||
})
|
})
|
||||||
deleteMemory(@Auth() auth: AuthDto, @Param() { id }: UUIDParamDto): Promise<void> {
|
deleteMemory(@Auth() auth: AuthDto, @Param() { id }: UUIDParamDto): Promise<void> {
|
||||||
return this.service.remove(auth, id);
|
return this.service.remove(auth, id);
|
||||||
|
|
@ -88,9 +95,10 @@ export class MemoryController {
|
||||||
|
|
||||||
@Put(':id/assets')
|
@Put(':id/assets')
|
||||||
@Authenticated({ permission: Permission.MemoryAssetCreate })
|
@Authenticated({ permission: Permission.MemoryAssetCreate })
|
||||||
@ApiOperation({
|
@Endpoint({
|
||||||
summary: 'Add assets to a memory',
|
summary: 'Add assets to a memory',
|
||||||
description: 'Add a list of asset IDs to a specific memory.',
|
description: 'Add a list of asset IDs to a specific memory.',
|
||||||
|
history: new HistoryBuilder().added('v1').beta('v1').stable('v2'),
|
||||||
})
|
})
|
||||||
addMemoryAssets(
|
addMemoryAssets(
|
||||||
@Auth() auth: AuthDto,
|
@Auth() auth: AuthDto,
|
||||||
|
|
@ -103,9 +111,10 @@ export class MemoryController {
|
||||||
@Delete(':id/assets')
|
@Delete(':id/assets')
|
||||||
@Authenticated({ permission: Permission.MemoryAssetDelete })
|
@Authenticated({ permission: Permission.MemoryAssetDelete })
|
||||||
@HttpCode(HttpStatus.OK)
|
@HttpCode(HttpStatus.OK)
|
||||||
@ApiOperation({
|
@Endpoint({
|
||||||
summary: 'Remove assets from a memory',
|
summary: 'Remove assets from a memory',
|
||||||
description: 'Remove a list of asset IDs from a specific memory.',
|
description: 'Remove a list of asset IDs from a specific memory.',
|
||||||
|
history: new HistoryBuilder().added('v1').beta('v1').stable('v2'),
|
||||||
})
|
})
|
||||||
removeMemoryAssets(
|
removeMemoryAssets(
|
||||||
@Auth() auth: AuthDto,
|
@Auth() auth: AuthDto,
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,6 @@
|
||||||
import { Body, Controller, HttpCode, HttpStatus, Param, Post } from '@nestjs/common';
|
import { Body, Controller, HttpCode, HttpStatus, Param, Post } from '@nestjs/common';
|
||||||
import { ApiOperation, ApiTags } from '@nestjs/swagger';
|
import { ApiTags } from '@nestjs/swagger';
|
||||||
|
import { Endpoint, HistoryBuilder } from 'src/decorators';
|
||||||
import { AuthDto } from 'src/dtos/auth.dto';
|
import { AuthDto } from 'src/dtos/auth.dto';
|
||||||
import {
|
import {
|
||||||
NotificationCreateDto,
|
NotificationCreateDto,
|
||||||
|
|
@ -21,9 +22,10 @@ export class NotificationAdminController {
|
||||||
|
|
||||||
@Post()
|
@Post()
|
||||||
@Authenticated({ admin: true })
|
@Authenticated({ admin: true })
|
||||||
@ApiOperation({
|
@Endpoint({
|
||||||
summary: 'Create a notification',
|
summary: 'Create a notification',
|
||||||
description: 'Create a new notification for a specific user.',
|
description: 'Create a new notification for a specific user.',
|
||||||
|
history: new HistoryBuilder().added('v1').beta('v1').stable('v2'),
|
||||||
})
|
})
|
||||||
createNotification(@Auth() auth: AuthDto, @Body() dto: NotificationCreateDto): Promise<NotificationDto> {
|
createNotification(@Auth() auth: AuthDto, @Body() dto: NotificationCreateDto): Promise<NotificationDto> {
|
||||||
return this.service.create(auth, dto);
|
return this.service.create(auth, dto);
|
||||||
|
|
@ -32,9 +34,10 @@ export class NotificationAdminController {
|
||||||
@Post('test-email')
|
@Post('test-email')
|
||||||
@Authenticated({ admin: true })
|
@Authenticated({ admin: true })
|
||||||
@HttpCode(HttpStatus.OK)
|
@HttpCode(HttpStatus.OK)
|
||||||
@ApiOperation({
|
@Endpoint({
|
||||||
summary: 'Send test email',
|
summary: 'Send test email',
|
||||||
description: 'Send a test email using the provided SMTP configuration.',
|
description: 'Send a test email using the provided SMTP configuration.',
|
||||||
|
history: new HistoryBuilder().added('v1').beta('v1').stable('v2'),
|
||||||
})
|
})
|
||||||
sendTestEmailAdmin(@Auth() auth: AuthDto, @Body() dto: SystemConfigSmtpDto): Promise<TestEmailResponseDto> {
|
sendTestEmailAdmin(@Auth() auth: AuthDto, @Body() dto: SystemConfigSmtpDto): Promise<TestEmailResponseDto> {
|
||||||
return this.service.sendTestEmail(auth.user.id, dto);
|
return this.service.sendTestEmail(auth.user.id, dto);
|
||||||
|
|
@ -43,9 +46,10 @@ export class NotificationAdminController {
|
||||||
@Post('templates/:name')
|
@Post('templates/:name')
|
||||||
@Authenticated({ admin: true })
|
@Authenticated({ admin: true })
|
||||||
@HttpCode(HttpStatus.OK)
|
@HttpCode(HttpStatus.OK)
|
||||||
@ApiOperation({
|
@Endpoint({
|
||||||
summary: 'Render email template',
|
summary: 'Render email template',
|
||||||
description: 'Retrieve a preview of the provided email template.',
|
description: 'Retrieve a preview of the provided email template.',
|
||||||
|
history: new HistoryBuilder().added('v1').beta('v1').stable('v2'),
|
||||||
})
|
})
|
||||||
getNotificationTemplateAdmin(
|
getNotificationTemplateAdmin(
|
||||||
@Auth() auth: AuthDto,
|
@Auth() auth: AuthDto,
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,6 @@
|
||||||
import { Body, Controller, Delete, Get, HttpCode, HttpStatus, Param, Put, Query } from '@nestjs/common';
|
import { Body, Controller, Delete, Get, HttpCode, HttpStatus, Param, Put, Query } from '@nestjs/common';
|
||||||
import { ApiOperation, ApiTags } from '@nestjs/swagger';
|
import { ApiTags } from '@nestjs/swagger';
|
||||||
|
import { Endpoint, HistoryBuilder } from 'src/decorators';
|
||||||
import { AuthDto } from 'src/dtos/auth.dto';
|
import { AuthDto } from 'src/dtos/auth.dto';
|
||||||
import {
|
import {
|
||||||
NotificationDeleteAllDto,
|
NotificationDeleteAllDto,
|
||||||
|
|
@ -20,9 +21,10 @@ export class NotificationController {
|
||||||
|
|
||||||
@Get()
|
@Get()
|
||||||
@Authenticated({ permission: Permission.NotificationRead })
|
@Authenticated({ permission: Permission.NotificationRead })
|
||||||
@ApiOperation({
|
@Endpoint({
|
||||||
summary: 'Retrieve notifications',
|
summary: 'Retrieve notifications',
|
||||||
description: 'Retrieve a list of notifications.',
|
description: 'Retrieve a list of notifications.',
|
||||||
|
history: new HistoryBuilder().added('v1').beta('v1').stable('v2'),
|
||||||
})
|
})
|
||||||
getNotifications(@Auth() auth: AuthDto, @Query() dto: NotificationSearchDto): Promise<NotificationDto[]> {
|
getNotifications(@Auth() auth: AuthDto, @Query() dto: NotificationSearchDto): Promise<NotificationDto[]> {
|
||||||
return this.service.search(auth, dto);
|
return this.service.search(auth, dto);
|
||||||
|
|
@ -31,9 +33,10 @@ export class NotificationController {
|
||||||
@Put()
|
@Put()
|
||||||
@Authenticated({ permission: Permission.NotificationUpdate })
|
@Authenticated({ permission: Permission.NotificationUpdate })
|
||||||
@HttpCode(HttpStatus.NO_CONTENT)
|
@HttpCode(HttpStatus.NO_CONTENT)
|
||||||
@ApiOperation({
|
@Endpoint({
|
||||||
summary: 'Update notifications',
|
summary: 'Update notifications',
|
||||||
description: 'Update a list of notifications. Allows to bulk-set the read status of notifications.',
|
description: 'Update a list of notifications. Allows to bulk-set the read status of notifications.',
|
||||||
|
history: new HistoryBuilder().added('v1').beta('v1').stable('v2'),
|
||||||
})
|
})
|
||||||
updateNotifications(@Auth() auth: AuthDto, @Body() dto: NotificationUpdateAllDto): Promise<void> {
|
updateNotifications(@Auth() auth: AuthDto, @Body() dto: NotificationUpdateAllDto): Promise<void> {
|
||||||
return this.service.updateAll(auth, dto);
|
return this.service.updateAll(auth, dto);
|
||||||
|
|
@ -42,9 +45,10 @@ export class NotificationController {
|
||||||
@Delete()
|
@Delete()
|
||||||
@Authenticated({ permission: Permission.NotificationDelete })
|
@Authenticated({ permission: Permission.NotificationDelete })
|
||||||
@HttpCode(HttpStatus.NO_CONTENT)
|
@HttpCode(HttpStatus.NO_CONTENT)
|
||||||
@ApiOperation({
|
@Endpoint({
|
||||||
summary: 'Delete notifications',
|
summary: 'Delete notifications',
|
||||||
description: 'Delete a list of notifications at once.',
|
description: 'Delete a list of notifications at once.',
|
||||||
|
history: new HistoryBuilder().added('v1').beta('v1').stable('v2'),
|
||||||
})
|
})
|
||||||
deleteNotifications(@Auth() auth: AuthDto, @Body() dto: NotificationDeleteAllDto): Promise<void> {
|
deleteNotifications(@Auth() auth: AuthDto, @Body() dto: NotificationDeleteAllDto): Promise<void> {
|
||||||
return this.service.deleteAll(auth, dto);
|
return this.service.deleteAll(auth, dto);
|
||||||
|
|
@ -52,9 +56,10 @@ export class NotificationController {
|
||||||
|
|
||||||
@Get(':id')
|
@Get(':id')
|
||||||
@Authenticated({ permission: Permission.NotificationRead })
|
@Authenticated({ permission: Permission.NotificationRead })
|
||||||
@ApiOperation({
|
@Endpoint({
|
||||||
summary: 'Get a notification',
|
summary: 'Get a notification',
|
||||||
description: 'Retrieve a specific notification identified by id.',
|
description: 'Retrieve a specific notification identified by id.',
|
||||||
|
history: new HistoryBuilder().added('v1').beta('v1').stable('v2'),
|
||||||
})
|
})
|
||||||
getNotification(@Auth() auth: AuthDto, @Param() { id }: UUIDParamDto): Promise<NotificationDto> {
|
getNotification(@Auth() auth: AuthDto, @Param() { id }: UUIDParamDto): Promise<NotificationDto> {
|
||||||
return this.service.get(auth, id);
|
return this.service.get(auth, id);
|
||||||
|
|
@ -62,9 +67,10 @@ export class NotificationController {
|
||||||
|
|
||||||
@Put(':id')
|
@Put(':id')
|
||||||
@Authenticated({ permission: Permission.NotificationUpdate })
|
@Authenticated({ permission: Permission.NotificationUpdate })
|
||||||
@ApiOperation({
|
@Endpoint({
|
||||||
summary: 'Update a notification',
|
summary: 'Update a notification',
|
||||||
description: 'Update a specific notification to set its read status.',
|
description: 'Update a specific notification to set its read status.',
|
||||||
|
history: new HistoryBuilder().added('v1').beta('v1').stable('v2'),
|
||||||
})
|
})
|
||||||
updateNotification(
|
updateNotification(
|
||||||
@Auth() auth: AuthDto,
|
@Auth() auth: AuthDto,
|
||||||
|
|
@ -77,9 +83,10 @@ export class NotificationController {
|
||||||
@Delete(':id')
|
@Delete(':id')
|
||||||
@Authenticated({ permission: Permission.NotificationDelete })
|
@Authenticated({ permission: Permission.NotificationDelete })
|
||||||
@HttpCode(HttpStatus.NO_CONTENT)
|
@HttpCode(HttpStatus.NO_CONTENT)
|
||||||
@ApiOperation({
|
@Endpoint({
|
||||||
summary: 'Delete a notification',
|
summary: 'Delete a notification',
|
||||||
description: 'Delete a specific notification.',
|
description: 'Delete a specific notification.',
|
||||||
|
history: new HistoryBuilder().added('v1').beta('v1').stable('v2'),
|
||||||
})
|
})
|
||||||
deleteNotification(@Auth() auth: AuthDto, @Param() { id }: UUIDParamDto): Promise<void> {
|
deleteNotification(@Auth() auth: AuthDto, @Param() { id }: UUIDParamDto): Promise<void> {
|
||||||
return this.service.delete(auth, id);
|
return this.service.delete(auth, id);
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
import { Body, Controller, Get, HttpCode, HttpStatus, Post, Redirect, Req, Res } from '@nestjs/common';
|
import { Body, Controller, Get, HttpCode, HttpStatus, Post, Redirect, Req, Res } from '@nestjs/common';
|
||||||
import { ApiOperation, ApiTags } from '@nestjs/swagger';
|
import { ApiTags } from '@nestjs/swagger';
|
||||||
import { Request, Response } from 'express';
|
import { Request, Response } from 'express';
|
||||||
|
import { Endpoint, HistoryBuilder } from 'src/decorators';
|
||||||
import {
|
import {
|
||||||
AuthDto,
|
AuthDto,
|
||||||
LoginResponseDto,
|
LoginResponseDto,
|
||||||
|
|
@ -21,10 +22,11 @@ export class OAuthController {
|
||||||
|
|
||||||
@Get('mobile-redirect')
|
@Get('mobile-redirect')
|
||||||
@Redirect()
|
@Redirect()
|
||||||
@ApiOperation({
|
@Endpoint({
|
||||||
summary: 'Redirect OAuth to mobile',
|
summary: 'Redirect OAuth to mobile',
|
||||||
description:
|
description:
|
||||||
'Requests to this URL are automatically forwarded to the mobile app, and is used in some cases for OAuth redirecting.',
|
'Requests to this URL are automatically forwarded to the mobile app, and is used in some cases for OAuth redirecting.',
|
||||||
|
history: new HistoryBuilder().added('v1').beta('v1').stable('v2'),
|
||||||
})
|
})
|
||||||
redirectOAuthToMobile(@Req() request: Request) {
|
redirectOAuthToMobile(@Req() request: Request) {
|
||||||
return {
|
return {
|
||||||
|
|
@ -34,9 +36,10 @@ export class OAuthController {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Post('authorize')
|
@Post('authorize')
|
||||||
@ApiOperation({
|
@Endpoint({
|
||||||
summary: 'Start OAuth',
|
summary: 'Start OAuth',
|
||||||
description: 'Initiate the OAuth authorization process.',
|
description: 'Initiate the OAuth authorization process.',
|
||||||
|
history: new HistoryBuilder().added('v1').beta('v1').stable('v2'),
|
||||||
})
|
})
|
||||||
async startOAuth(
|
async startOAuth(
|
||||||
@Body() dto: OAuthConfigDto,
|
@Body() dto: OAuthConfigDto,
|
||||||
|
|
@ -58,9 +61,10 @@ export class OAuthController {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Post('callback')
|
@Post('callback')
|
||||||
@ApiOperation({
|
@Endpoint({
|
||||||
summary: 'Finish OAuth',
|
summary: 'Finish OAuth',
|
||||||
description: 'Complete the OAuth authorization process by exchanging the authorization code for a session token.',
|
description: 'Complete the OAuth authorization process by exchanging the authorization code for a session token.',
|
||||||
|
history: new HistoryBuilder().added('v1').beta('v1').stable('v2'),
|
||||||
})
|
})
|
||||||
async finishOAuth(
|
async finishOAuth(
|
||||||
@Req() request: Request,
|
@Req() request: Request,
|
||||||
|
|
@ -84,9 +88,10 @@ export class OAuthController {
|
||||||
@Post('link')
|
@Post('link')
|
||||||
@Authenticated()
|
@Authenticated()
|
||||||
@HttpCode(HttpStatus.OK)
|
@HttpCode(HttpStatus.OK)
|
||||||
@ApiOperation({
|
@Endpoint({
|
||||||
summary: 'Link OAuth account',
|
summary: 'Link OAuth account',
|
||||||
description: 'Link an OAuth account to the authenticated user.',
|
description: 'Link an OAuth account to the authenticated user.',
|
||||||
|
history: new HistoryBuilder().added('v1').beta('v1').stable('v2'),
|
||||||
})
|
})
|
||||||
linkOAuthAccount(
|
linkOAuthAccount(
|
||||||
@Req() request: Request,
|
@Req() request: Request,
|
||||||
|
|
@ -99,9 +104,10 @@ export class OAuthController {
|
||||||
@Post('unlink')
|
@Post('unlink')
|
||||||
@Authenticated()
|
@Authenticated()
|
||||||
@HttpCode(HttpStatus.OK)
|
@HttpCode(HttpStatus.OK)
|
||||||
@ApiOperation({
|
@Endpoint({
|
||||||
summary: 'Unlink OAuth account',
|
summary: 'Unlink OAuth account',
|
||||||
description: 'Unlink the OAuth account from the authenticated user.',
|
description: 'Unlink the OAuth account from the authenticated user.',
|
||||||
|
history: new HistoryBuilder().added('v1').beta('v1').stable('v2'),
|
||||||
})
|
})
|
||||||
unlinkOAuthAccount(@Auth() auth: AuthDto): Promise<UserAdminResponseDto> {
|
unlinkOAuthAccount(@Auth() auth: AuthDto): Promise<UserAdminResponseDto> {
|
||||||
return this.service.unlink(auth);
|
return this.service.unlink(auth);
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
import { Body, Controller, Delete, Get, HttpCode, HttpStatus, Param, Post, Put, Query } from '@nestjs/common';
|
import { Body, Controller, Delete, Get, HttpCode, HttpStatus, Param, Post, Put, Query } from '@nestjs/common';
|
||||||
import { ApiOperation, ApiTags } from '@nestjs/swagger';
|
import { ApiTags } from '@nestjs/swagger';
|
||||||
import { EndpointLifecycle } from 'src/decorators';
|
import { Endpoint, HistoryBuilder } from 'src/decorators';
|
||||||
import { AuthDto } from 'src/dtos/auth.dto';
|
import { AuthDto } from 'src/dtos/auth.dto';
|
||||||
import { PartnerCreateDto, PartnerResponseDto, PartnerSearchDto, PartnerUpdateDto } from 'src/dtos/partner.dto';
|
import { PartnerCreateDto, PartnerResponseDto, PartnerSearchDto, PartnerUpdateDto } from 'src/dtos/partner.dto';
|
||||||
import { ApiTag, Permission } from 'src/enum';
|
import { ApiTag, Permission } from 'src/enum';
|
||||||
|
|
@ -15,9 +15,10 @@ export class PartnerController {
|
||||||
|
|
||||||
@Get()
|
@Get()
|
||||||
@Authenticated({ permission: Permission.PartnerRead })
|
@Authenticated({ permission: Permission.PartnerRead })
|
||||||
@ApiOperation({
|
@Endpoint({
|
||||||
summary: 'Retrieve partners',
|
summary: 'Retrieve partners',
|
||||||
description: 'Retrieve a list of partners with whom assets are shared.',
|
description: 'Retrieve a list of partners with whom assets are shared.',
|
||||||
|
history: new HistoryBuilder().added('v1').beta('v1').stable('v2'),
|
||||||
})
|
})
|
||||||
getPartners(@Auth() auth: AuthDto, @Query() dto: PartnerSearchDto): Promise<PartnerResponseDto[]> {
|
getPartners(@Auth() auth: AuthDto, @Query() dto: PartnerSearchDto): Promise<PartnerResponseDto[]> {
|
||||||
return this.service.search(auth, dto);
|
return this.service.search(auth, dto);
|
||||||
|
|
@ -25,19 +26,20 @@ export class PartnerController {
|
||||||
|
|
||||||
@Post()
|
@Post()
|
||||||
@Authenticated({ permission: Permission.PartnerCreate })
|
@Authenticated({ permission: Permission.PartnerCreate })
|
||||||
@ApiOperation({
|
@Endpoint({
|
||||||
summary: 'Create a partner',
|
summary: 'Create a partner',
|
||||||
description: 'Create a new partner to share assets with.',
|
description: 'Create a new partner to share assets with.',
|
||||||
|
history: new HistoryBuilder().added('v1').beta('v1').stable('v2'),
|
||||||
})
|
})
|
||||||
createPartner(@Auth() auth: AuthDto, @Body() dto: PartnerCreateDto): Promise<PartnerResponseDto> {
|
createPartner(@Auth() auth: AuthDto, @Body() dto: PartnerCreateDto): Promise<PartnerResponseDto> {
|
||||||
return this.service.create(auth, dto);
|
return this.service.create(auth, dto);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Post(':id')
|
@Post(':id')
|
||||||
@EndpointLifecycle({
|
@Endpoint({
|
||||||
deprecatedAt: 'v1.141.0',
|
|
||||||
summary: 'Create a partner',
|
summary: 'Create a partner',
|
||||||
description: 'Create a new partner to share assets with.',
|
description: 'Create a new partner to share assets with.',
|
||||||
|
history: new HistoryBuilder().added('v1').deprecated('v1', { replacementId: 'createPartner' }),
|
||||||
})
|
})
|
||||||
@Authenticated({ permission: Permission.PartnerCreate })
|
@Authenticated({ permission: Permission.PartnerCreate })
|
||||||
createPartnerDeprecated(@Auth() auth: AuthDto, @Param() { id }: UUIDParamDto): Promise<PartnerResponseDto> {
|
createPartnerDeprecated(@Auth() auth: AuthDto, @Param() { id }: UUIDParamDto): Promise<PartnerResponseDto> {
|
||||||
|
|
@ -46,9 +48,10 @@ export class PartnerController {
|
||||||
|
|
||||||
@Put(':id')
|
@Put(':id')
|
||||||
@Authenticated({ permission: Permission.PartnerUpdate })
|
@Authenticated({ permission: Permission.PartnerUpdate })
|
||||||
@ApiOperation({
|
@Endpoint({
|
||||||
summary: 'Update a partner',
|
summary: 'Update a partner',
|
||||||
description: "Specify whether a partner's assets should appear in the user's timeline.",
|
description: "Specify whether a partner's assets should appear in the user's timeline.",
|
||||||
|
history: new HistoryBuilder().added('v1').beta('v1').stable('v2'),
|
||||||
})
|
})
|
||||||
updatePartner(
|
updatePartner(
|
||||||
@Auth() auth: AuthDto,
|
@Auth() auth: AuthDto,
|
||||||
|
|
@ -61,9 +64,10 @@ export class PartnerController {
|
||||||
@Delete(':id')
|
@Delete(':id')
|
||||||
@Authenticated({ permission: Permission.PartnerDelete })
|
@Authenticated({ permission: Permission.PartnerDelete })
|
||||||
@HttpCode(HttpStatus.NO_CONTENT)
|
@HttpCode(HttpStatus.NO_CONTENT)
|
||||||
@ApiOperation({
|
@Endpoint({
|
||||||
summary: 'Remove a partner',
|
summary: 'Remove a partner',
|
||||||
description: 'Stop sharing assets with a partner.',
|
description: 'Stop sharing assets with a partner.',
|
||||||
|
history: new HistoryBuilder().added('v1').beta('v1').stable('v2'),
|
||||||
})
|
})
|
||||||
removePartner(@Auth() auth: AuthDto, @Param() { id }: UUIDParamDto): Promise<void> {
|
removePartner(@Auth() auth: AuthDto, @Param() { id }: UUIDParamDto): Promise<void> {
|
||||||
return this.service.remove(auth, id);
|
return this.service.remove(auth, id);
|
||||||
|
|
|
||||||
|
|
@ -12,8 +12,9 @@ import {
|
||||||
Query,
|
Query,
|
||||||
Res,
|
Res,
|
||||||
} from '@nestjs/common';
|
} from '@nestjs/common';
|
||||||
import { ApiOperation, ApiTags } from '@nestjs/swagger';
|
import { ApiTags } from '@nestjs/swagger';
|
||||||
import { NextFunction, Response } from 'express';
|
import { NextFunction, Response } from 'express';
|
||||||
|
import { Endpoint, HistoryBuilder } from 'src/decorators';
|
||||||
import { BulkIdResponseDto, BulkIdsDto } from 'src/dtos/asset-ids.response.dto';
|
import { BulkIdResponseDto, BulkIdsDto } from 'src/dtos/asset-ids.response.dto';
|
||||||
import { AuthDto } from 'src/dtos/auth.dto';
|
import { AuthDto } from 'src/dtos/auth.dto';
|
||||||
import {
|
import {
|
||||||
|
|
@ -46,16 +47,21 @@ export class PersonController {
|
||||||
|
|
||||||
@Get()
|
@Get()
|
||||||
@Authenticated({ permission: Permission.PersonRead })
|
@Authenticated({ permission: Permission.PersonRead })
|
||||||
@ApiOperation({ summary: 'Get all people', description: 'Retrieve a list of all people.' })
|
@Endpoint({
|
||||||
|
summary: 'Get all people',
|
||||||
|
description: 'Retrieve a list of all people.',
|
||||||
|
history: new HistoryBuilder().added('v1').beta('v1').stable('v2'),
|
||||||
|
})
|
||||||
getAllPeople(@Auth() auth: AuthDto, @Query() options: PersonSearchDto): Promise<PeopleResponseDto> {
|
getAllPeople(@Auth() auth: AuthDto, @Query() options: PersonSearchDto): Promise<PeopleResponseDto> {
|
||||||
return this.service.getAll(auth, options);
|
return this.service.getAll(auth, options);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Post()
|
@Post()
|
||||||
@Authenticated({ permission: Permission.PersonCreate })
|
@Authenticated({ permission: Permission.PersonCreate })
|
||||||
@ApiOperation({
|
@Endpoint({
|
||||||
summary: 'Create a person',
|
summary: 'Create a person',
|
||||||
description: 'Create a new person that can have multiple faces assigned to them.',
|
description: 'Create a new person that can have multiple faces assigned to them.',
|
||||||
|
history: new HistoryBuilder().added('v1').beta('v1').stable('v2'),
|
||||||
})
|
})
|
||||||
createPerson(@Auth() auth: AuthDto, @Body() dto: PersonCreateDto): Promise<PersonResponseDto> {
|
createPerson(@Auth() auth: AuthDto, @Body() dto: PersonCreateDto): Promise<PersonResponseDto> {
|
||||||
return this.service.create(auth, dto);
|
return this.service.create(auth, dto);
|
||||||
|
|
@ -63,7 +69,11 @@ export class PersonController {
|
||||||
|
|
||||||
@Put()
|
@Put()
|
||||||
@Authenticated({ permission: Permission.PersonUpdate })
|
@Authenticated({ permission: Permission.PersonUpdate })
|
||||||
@ApiOperation({ summary: 'Update people', description: 'Bulk update multiple people at once.' })
|
@Endpoint({
|
||||||
|
summary: 'Update people',
|
||||||
|
description: 'Bulk update multiple people at once.',
|
||||||
|
history: new HistoryBuilder().added('v1').beta('v1').stable('v2'),
|
||||||
|
})
|
||||||
updatePeople(@Auth() auth: AuthDto, @Body() dto: PeopleUpdateDto): Promise<BulkIdResponseDto[]> {
|
updatePeople(@Auth() auth: AuthDto, @Body() dto: PeopleUpdateDto): Promise<BulkIdResponseDto[]> {
|
||||||
return this.service.updateAll(auth, dto);
|
return this.service.updateAll(auth, dto);
|
||||||
}
|
}
|
||||||
|
|
@ -71,21 +81,33 @@ export class PersonController {
|
||||||
@Delete()
|
@Delete()
|
||||||
@Authenticated({ permission: Permission.PersonDelete })
|
@Authenticated({ permission: Permission.PersonDelete })
|
||||||
@HttpCode(HttpStatus.NO_CONTENT)
|
@HttpCode(HttpStatus.NO_CONTENT)
|
||||||
@ApiOperation({ summary: 'Delete people', description: 'Bulk delete a list of people at once.' })
|
@Endpoint({
|
||||||
|
summary: 'Delete people',
|
||||||
|
description: 'Bulk delete a list of people at once.',
|
||||||
|
history: new HistoryBuilder().added('v1').beta('v1').stable('v2'),
|
||||||
|
})
|
||||||
deletePeople(@Auth() auth: AuthDto, @Body() dto: BulkIdsDto): Promise<void> {
|
deletePeople(@Auth() auth: AuthDto, @Body() dto: BulkIdsDto): Promise<void> {
|
||||||
return this.service.deleteAll(auth, dto);
|
return this.service.deleteAll(auth, dto);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Get(':id')
|
@Get(':id')
|
||||||
@Authenticated({ permission: Permission.PersonRead })
|
@Authenticated({ permission: Permission.PersonRead })
|
||||||
@ApiOperation({ summary: 'Get a person', description: 'Retrieve a person by id.' })
|
@Endpoint({
|
||||||
|
summary: 'Get a person',
|
||||||
|
description: 'Retrieve a person by id.',
|
||||||
|
history: new HistoryBuilder().added('v1').beta('v1').stable('v2'),
|
||||||
|
})
|
||||||
getPerson(@Auth() auth: AuthDto, @Param() { id }: UUIDParamDto): Promise<PersonResponseDto> {
|
getPerson(@Auth() auth: AuthDto, @Param() { id }: UUIDParamDto): Promise<PersonResponseDto> {
|
||||||
return this.service.getById(auth, id);
|
return this.service.getById(auth, id);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Put(':id')
|
@Put(':id')
|
||||||
@Authenticated({ permission: Permission.PersonUpdate })
|
@Authenticated({ permission: Permission.PersonUpdate })
|
||||||
@ApiOperation({ summary: 'Update person', description: 'Update an individual person.' })
|
@Endpoint({
|
||||||
|
summary: 'Update person',
|
||||||
|
description: 'Update an individual person.',
|
||||||
|
history: new HistoryBuilder().added('v1').beta('v1').stable('v2'),
|
||||||
|
})
|
||||||
updatePerson(
|
updatePerson(
|
||||||
@Auth() auth: AuthDto,
|
@Auth() auth: AuthDto,
|
||||||
@Param() { id }: UUIDParamDto,
|
@Param() { id }: UUIDParamDto,
|
||||||
|
|
@ -97,14 +119,22 @@ export class PersonController {
|
||||||
@Delete(':id')
|
@Delete(':id')
|
||||||
@Authenticated({ permission: Permission.PersonDelete })
|
@Authenticated({ permission: Permission.PersonDelete })
|
||||||
@HttpCode(HttpStatus.NO_CONTENT)
|
@HttpCode(HttpStatus.NO_CONTENT)
|
||||||
@ApiOperation({ summary: 'Delete person', description: 'Delete an individual person.' })
|
@Endpoint({
|
||||||
|
summary: 'Delete person',
|
||||||
|
description: 'Delete an individual person.',
|
||||||
|
history: new HistoryBuilder().added('v1').beta('v1').stable('v2'),
|
||||||
|
})
|
||||||
deletePerson(@Auth() auth: AuthDto, @Param() { id }: UUIDParamDto): Promise<void> {
|
deletePerson(@Auth() auth: AuthDto, @Param() { id }: UUIDParamDto): Promise<void> {
|
||||||
return this.service.delete(auth, id);
|
return this.service.delete(auth, id);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Get(':id/statistics')
|
@Get(':id/statistics')
|
||||||
@Authenticated({ permission: Permission.PersonStatistics })
|
@Authenticated({ permission: Permission.PersonStatistics })
|
||||||
@ApiOperation({ summary: 'Get person statistics', description: 'Retrieve statistics about a specific person.' })
|
@Endpoint({
|
||||||
|
summary: 'Get person statistics',
|
||||||
|
description: 'Retrieve statistics about a specific person.',
|
||||||
|
history: new HistoryBuilder().added('v1').beta('v1').stable('v2'),
|
||||||
|
})
|
||||||
getPersonStatistics(@Auth() auth: AuthDto, @Param() { id }: UUIDParamDto): Promise<PersonStatisticsResponseDto> {
|
getPersonStatistics(@Auth() auth: AuthDto, @Param() { id }: UUIDParamDto): Promise<PersonStatisticsResponseDto> {
|
||||||
return this.service.getStatistics(auth, id);
|
return this.service.getStatistics(auth, id);
|
||||||
}
|
}
|
||||||
|
|
@ -112,7 +142,11 @@ export class PersonController {
|
||||||
@Get(':id/thumbnail')
|
@Get(':id/thumbnail')
|
||||||
@FileResponse()
|
@FileResponse()
|
||||||
@Authenticated({ permission: Permission.PersonRead })
|
@Authenticated({ permission: Permission.PersonRead })
|
||||||
@ApiOperation({ summary: 'Get person thumbnail', description: 'Retrieve the thumbnail file for a person.' })
|
@Endpoint({
|
||||||
|
summary: 'Get person thumbnail',
|
||||||
|
description: 'Retrieve the thumbnail file for a person.',
|
||||||
|
history: new HistoryBuilder().added('v1').beta('v1').stable('v2'),
|
||||||
|
})
|
||||||
async getPersonThumbnail(
|
async getPersonThumbnail(
|
||||||
@Res() res: Response,
|
@Res() res: Response,
|
||||||
@Next() next: NextFunction,
|
@Next() next: NextFunction,
|
||||||
|
|
@ -124,7 +158,11 @@ export class PersonController {
|
||||||
|
|
||||||
@Put(':id/reassign')
|
@Put(':id/reassign')
|
||||||
@Authenticated({ permission: Permission.PersonReassign })
|
@Authenticated({ permission: Permission.PersonReassign })
|
||||||
@ApiOperation({ summary: 'Reassign faces', description: 'Bulk reassign a list of faces to a different person.' })
|
@Endpoint({
|
||||||
|
summary: 'Reassign faces',
|
||||||
|
description: 'Bulk reassign a list of faces to a different person.',
|
||||||
|
history: new HistoryBuilder().added('v1').beta('v1').stable('v2'),
|
||||||
|
})
|
||||||
reassignFaces(
|
reassignFaces(
|
||||||
@Auth() auth: AuthDto,
|
@Auth() auth: AuthDto,
|
||||||
@Param() { id }: UUIDParamDto,
|
@Param() { id }: UUIDParamDto,
|
||||||
|
|
@ -136,9 +174,10 @@ export class PersonController {
|
||||||
@Post(':id/merge')
|
@Post(':id/merge')
|
||||||
@Authenticated({ permission: Permission.PersonMerge })
|
@Authenticated({ permission: Permission.PersonMerge })
|
||||||
@HttpCode(HttpStatus.OK)
|
@HttpCode(HttpStatus.OK)
|
||||||
@ApiOperation({
|
@Endpoint({
|
||||||
summary: 'Merge people',
|
summary: 'Merge people',
|
||||||
description: 'Merge a list of people into the person specified in the path parameter.',
|
description: 'Merge a list of people into the person specified in the path parameter.',
|
||||||
|
history: new HistoryBuilder().added('v1').beta('v1').stable('v2'),
|
||||||
})
|
})
|
||||||
mergePerson(
|
mergePerson(
|
||||||
@Auth() auth: AuthDto,
|
@Auth() auth: AuthDto,
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,6 @@
|
||||||
import { Body, Controller, Get, HttpCode, HttpStatus, Post, Query } from '@nestjs/common';
|
import { Body, Controller, Get, HttpCode, HttpStatus, Post, Query } from '@nestjs/common';
|
||||||
import { ApiOperation, ApiTags } from '@nestjs/swagger';
|
import { ApiTags } from '@nestjs/swagger';
|
||||||
|
import { Endpoint, HistoryBuilder } from 'src/decorators';
|
||||||
import { AssetResponseDto } from 'src/dtos/asset-response.dto';
|
import { AssetResponseDto } from 'src/dtos/asset-response.dto';
|
||||||
import { AuthDto } from 'src/dtos/auth.dto';
|
import { AuthDto } from 'src/dtos/auth.dto';
|
||||||
import { PersonResponseDto } from 'src/dtos/person.dto';
|
import { PersonResponseDto } from 'src/dtos/person.dto';
|
||||||
|
|
@ -29,9 +30,10 @@ export class SearchController {
|
||||||
@Post('metadata')
|
@Post('metadata')
|
||||||
@Authenticated({ permission: Permission.AssetRead })
|
@Authenticated({ permission: Permission.AssetRead })
|
||||||
@HttpCode(HttpStatus.OK)
|
@HttpCode(HttpStatus.OK)
|
||||||
@ApiOperation({
|
@Endpoint({
|
||||||
summary: 'Search assets by metadata',
|
summary: 'Search assets by metadata',
|
||||||
description: 'Search for assets based on various metadata criteria.',
|
description: 'Search for assets based on various metadata criteria.',
|
||||||
|
history: new HistoryBuilder().added('v1').beta('v1').stable('v2'),
|
||||||
})
|
})
|
||||||
searchAssets(@Auth() auth: AuthDto, @Body() dto: MetadataSearchDto): Promise<SearchResponseDto> {
|
searchAssets(@Auth() auth: AuthDto, @Body() dto: MetadataSearchDto): Promise<SearchResponseDto> {
|
||||||
return this.service.searchMetadata(auth, dto);
|
return this.service.searchMetadata(auth, dto);
|
||||||
|
|
@ -40,9 +42,10 @@ export class SearchController {
|
||||||
@Post('statistics')
|
@Post('statistics')
|
||||||
@Authenticated({ permission: Permission.AssetStatistics })
|
@Authenticated({ permission: Permission.AssetStatistics })
|
||||||
@HttpCode(HttpStatus.OK)
|
@HttpCode(HttpStatus.OK)
|
||||||
@ApiOperation({
|
@Endpoint({
|
||||||
summary: 'Search asset statistics',
|
summary: 'Search asset statistics',
|
||||||
description: 'Retrieve statistical data about assets based on search criteria, such as the total matching count.',
|
description: 'Retrieve statistical data about assets based on search criteria, such as the total matching count.',
|
||||||
|
history: new HistoryBuilder().added('v1').beta('v1').stable('v2'),
|
||||||
})
|
})
|
||||||
searchAssetStatistics(@Auth() auth: AuthDto, @Body() dto: StatisticsSearchDto): Promise<SearchStatisticsResponseDto> {
|
searchAssetStatistics(@Auth() auth: AuthDto, @Body() dto: StatisticsSearchDto): Promise<SearchStatisticsResponseDto> {
|
||||||
return this.service.searchStatistics(auth, dto);
|
return this.service.searchStatistics(auth, dto);
|
||||||
|
|
@ -51,9 +54,10 @@ export class SearchController {
|
||||||
@Post('random')
|
@Post('random')
|
||||||
@Authenticated({ permission: Permission.AssetRead })
|
@Authenticated({ permission: Permission.AssetRead })
|
||||||
@HttpCode(HttpStatus.OK)
|
@HttpCode(HttpStatus.OK)
|
||||||
@ApiOperation({
|
@Endpoint({
|
||||||
summary: 'Search random assets',
|
summary: 'Search random assets',
|
||||||
description: 'Retrieve a random selection of assets based on the provided criteria.',
|
description: 'Retrieve a random selection of assets based on the provided criteria.',
|
||||||
|
history: new HistoryBuilder().added('v1').beta('v1').stable('v2'),
|
||||||
})
|
})
|
||||||
searchRandom(@Auth() auth: AuthDto, @Body() dto: RandomSearchDto): Promise<AssetResponseDto[]> {
|
searchRandom(@Auth() auth: AuthDto, @Body() dto: RandomSearchDto): Promise<AssetResponseDto[]> {
|
||||||
return this.service.searchRandom(auth, dto);
|
return this.service.searchRandom(auth, dto);
|
||||||
|
|
@ -62,9 +66,10 @@ export class SearchController {
|
||||||
@Post('large-assets')
|
@Post('large-assets')
|
||||||
@Authenticated({ permission: Permission.AssetRead })
|
@Authenticated({ permission: Permission.AssetRead })
|
||||||
@HttpCode(HttpStatus.OK)
|
@HttpCode(HttpStatus.OK)
|
||||||
@ApiOperation({
|
@Endpoint({
|
||||||
summary: 'Search large assets',
|
summary: 'Search large assets',
|
||||||
description: 'Search for assets that are considered large based on specified criteria.',
|
description: 'Search for assets that are considered large based on specified criteria.',
|
||||||
|
history: new HistoryBuilder().added('v1').beta('v1').stable('v2'),
|
||||||
})
|
})
|
||||||
searchLargeAssets(@Auth() auth: AuthDto, @Query() dto: LargeAssetSearchDto): Promise<AssetResponseDto[]> {
|
searchLargeAssets(@Auth() auth: AuthDto, @Query() dto: LargeAssetSearchDto): Promise<AssetResponseDto[]> {
|
||||||
return this.service.searchLargeAssets(auth, dto);
|
return this.service.searchLargeAssets(auth, dto);
|
||||||
|
|
@ -73,9 +78,10 @@ export class SearchController {
|
||||||
@Post('smart')
|
@Post('smart')
|
||||||
@Authenticated({ permission: Permission.AssetRead })
|
@Authenticated({ permission: Permission.AssetRead })
|
||||||
@HttpCode(HttpStatus.OK)
|
@HttpCode(HttpStatus.OK)
|
||||||
@ApiOperation({
|
@Endpoint({
|
||||||
summary: 'Smart asset search',
|
summary: 'Smart asset search',
|
||||||
description: 'Perform a smart search for assets by using machine learning vectors to determine relevance.',
|
description: 'Perform a smart search for assets by using machine learning vectors to determine relevance.',
|
||||||
|
history: new HistoryBuilder().added('v1').beta('v1').stable('v2'),
|
||||||
})
|
})
|
||||||
searchSmart(@Auth() auth: AuthDto, @Body() dto: SmartSearchDto): Promise<SearchResponseDto> {
|
searchSmart(@Auth() auth: AuthDto, @Body() dto: SmartSearchDto): Promise<SearchResponseDto> {
|
||||||
return this.service.searchSmart(auth, dto);
|
return this.service.searchSmart(auth, dto);
|
||||||
|
|
@ -83,9 +89,10 @@ export class SearchController {
|
||||||
|
|
||||||
@Get('explore')
|
@Get('explore')
|
||||||
@Authenticated({ permission: Permission.AssetRead })
|
@Authenticated({ permission: Permission.AssetRead })
|
||||||
@ApiOperation({
|
@Endpoint({
|
||||||
summary: 'Retrieve explore data',
|
summary: 'Retrieve explore data',
|
||||||
description: 'Retrieve data for the explore section, such as popular people and places.',
|
description: 'Retrieve data for the explore section, such as popular people and places.',
|
||||||
|
history: new HistoryBuilder().added('v1').beta('v1').stable('v2'),
|
||||||
})
|
})
|
||||||
getExploreData(@Auth() auth: AuthDto): Promise<SearchExploreResponseDto[]> {
|
getExploreData(@Auth() auth: AuthDto): Promise<SearchExploreResponseDto[]> {
|
||||||
return this.service.getExploreData(auth);
|
return this.service.getExploreData(auth);
|
||||||
|
|
@ -93,9 +100,10 @@ export class SearchController {
|
||||||
|
|
||||||
@Get('person')
|
@Get('person')
|
||||||
@Authenticated({ permission: Permission.PersonRead })
|
@Authenticated({ permission: Permission.PersonRead })
|
||||||
@ApiOperation({
|
@Endpoint({
|
||||||
summary: 'Search people',
|
summary: 'Search people',
|
||||||
description: 'Search for people by name.',
|
description: 'Search for people by name.',
|
||||||
|
history: new HistoryBuilder().added('v1').beta('v1').stable('v2'),
|
||||||
})
|
})
|
||||||
searchPerson(@Auth() auth: AuthDto, @Query() dto: SearchPeopleDto): Promise<PersonResponseDto[]> {
|
searchPerson(@Auth() auth: AuthDto, @Query() dto: SearchPeopleDto): Promise<PersonResponseDto[]> {
|
||||||
return this.service.searchPerson(auth, dto);
|
return this.service.searchPerson(auth, dto);
|
||||||
|
|
@ -103,9 +111,10 @@ export class SearchController {
|
||||||
|
|
||||||
@Get('places')
|
@Get('places')
|
||||||
@Authenticated({ permission: Permission.AssetRead })
|
@Authenticated({ permission: Permission.AssetRead })
|
||||||
@ApiOperation({
|
@Endpoint({
|
||||||
summary: 'Search places',
|
summary: 'Search places',
|
||||||
description: 'Search for places by name.',
|
description: 'Search for places by name.',
|
||||||
|
history: new HistoryBuilder().added('v1').beta('v1').stable('v2'),
|
||||||
})
|
})
|
||||||
searchPlaces(@Query() dto: SearchPlacesDto): Promise<PlacesResponseDto[]> {
|
searchPlaces(@Query() dto: SearchPlacesDto): Promise<PlacesResponseDto[]> {
|
||||||
return this.service.searchPlaces(dto);
|
return this.service.searchPlaces(dto);
|
||||||
|
|
@ -113,10 +122,11 @@ export class SearchController {
|
||||||
|
|
||||||
@Get('cities')
|
@Get('cities')
|
||||||
@Authenticated({ permission: Permission.AssetRead })
|
@Authenticated({ permission: Permission.AssetRead })
|
||||||
@ApiOperation({
|
@Endpoint({
|
||||||
summary: 'Retrieve assets by city',
|
summary: 'Retrieve assets by city',
|
||||||
description:
|
description:
|
||||||
'Retrieve a list of assets with each asset belonging to a different city. This endpoint is used on the places pages to show a single thumbnail for each city the user has assets in.',
|
'Retrieve a list of assets with each asset belonging to a different city. This endpoint is used on the places pages to show a single thumbnail for each city the user has assets in.',
|
||||||
|
history: new HistoryBuilder().added('v1').beta('v1').stable('v2'),
|
||||||
})
|
})
|
||||||
getAssetsByCity(@Auth() auth: AuthDto): Promise<AssetResponseDto[]> {
|
getAssetsByCity(@Auth() auth: AuthDto): Promise<AssetResponseDto[]> {
|
||||||
return this.service.getAssetsByCity(auth);
|
return this.service.getAssetsByCity(auth);
|
||||||
|
|
@ -124,10 +134,11 @@ export class SearchController {
|
||||||
|
|
||||||
@Get('suggestions')
|
@Get('suggestions')
|
||||||
@Authenticated({ permission: Permission.AssetRead })
|
@Authenticated({ permission: Permission.AssetRead })
|
||||||
@ApiOperation({
|
@Endpoint({
|
||||||
summary: 'Retrieve search suggestions',
|
summary: 'Retrieve search suggestions',
|
||||||
description:
|
description:
|
||||||
'Retrieve search suggestions based on partial input. This endpoint is used for typeahead search features.',
|
'Retrieve search suggestions based on partial input. This endpoint is used for typeahead search features.',
|
||||||
|
history: new HistoryBuilder().added('v1').beta('v1').stable('v2'),
|
||||||
})
|
})
|
||||||
getSearchSuggestions(@Auth() auth: AuthDto, @Query() dto: SearchSuggestionRequestDto): Promise<string[]> {
|
getSearchSuggestions(@Auth() auth: AuthDto, @Query() dto: SearchSuggestionRequestDto): Promise<string[]> {
|
||||||
// TODO fix open api generation to indicate that results can be nullable
|
// TODO fix open api generation to indicate that results can be nullable
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,6 @@
|
||||||
import { Body, Controller, Delete, Get, HttpCode, HttpStatus, Put } from '@nestjs/common';
|
import { Body, Controller, Delete, Get, HttpCode, HttpStatus, Put } from '@nestjs/common';
|
||||||
import { ApiNotFoundResponse, ApiOperation, ApiTags } from '@nestjs/swagger';
|
import { ApiNotFoundResponse, ApiTags } from '@nestjs/swagger';
|
||||||
|
import { Endpoint, HistoryBuilder } from 'src/decorators';
|
||||||
import { LicenseKeyDto, LicenseResponseDto } from 'src/dtos/license.dto';
|
import { LicenseKeyDto, LicenseResponseDto } from 'src/dtos/license.dto';
|
||||||
import {
|
import {
|
||||||
ServerAboutResponseDto,
|
ServerAboutResponseDto,
|
||||||
|
|
@ -32,84 +33,113 @@ export class ServerController {
|
||||||
|
|
||||||
@Get('about')
|
@Get('about')
|
||||||
@Authenticated({ permission: Permission.ServerAbout })
|
@Authenticated({ permission: Permission.ServerAbout })
|
||||||
@ApiOperation({ summary: 'Get server information', description: 'Retrieve a list of information about the server.' })
|
@Endpoint({
|
||||||
|
summary: 'Get server information',
|
||||||
|
description: 'Retrieve a list of information about the server.',
|
||||||
|
history: new HistoryBuilder().added('v1').beta('v1').stable('v2'),
|
||||||
|
})
|
||||||
getAboutInfo(): Promise<ServerAboutResponseDto> {
|
getAboutInfo(): Promise<ServerAboutResponseDto> {
|
||||||
return this.service.getAboutInfo();
|
return this.service.getAboutInfo();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Get('apk-links')
|
@Get('apk-links')
|
||||||
@Authenticated({ permission: Permission.ServerApkLinks })
|
@Authenticated({ permission: Permission.ServerApkLinks })
|
||||||
@ApiOperation({ summary: 'Get APK links', description: 'Retrieve links to the APKs for the current server version.' })
|
@Endpoint({
|
||||||
|
summary: 'Get APK links',
|
||||||
|
description: 'Retrieve links to the APKs for the current server version.',
|
||||||
|
history: new HistoryBuilder().added('v1').beta('v1').stable('v2'),
|
||||||
|
})
|
||||||
getApkLinks(): ServerApkLinksDto {
|
getApkLinks(): ServerApkLinksDto {
|
||||||
return this.service.getApkLinks();
|
return this.service.getApkLinks();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Get('storage')
|
@Get('storage')
|
||||||
@Authenticated({ permission: Permission.ServerStorage })
|
@Authenticated({ permission: Permission.ServerStorage })
|
||||||
@ApiOperation({
|
@Endpoint({
|
||||||
summary: 'Get storage',
|
summary: 'Get storage',
|
||||||
description: 'Retrieve the current storage utilization information of the server.',
|
description: 'Retrieve the current storage utilization information of the server.',
|
||||||
|
history: new HistoryBuilder().added('v1').beta('v1').stable('v2'),
|
||||||
})
|
})
|
||||||
getStorage(): Promise<ServerStorageResponseDto> {
|
getStorage(): Promise<ServerStorageResponseDto> {
|
||||||
return this.service.getStorage();
|
return this.service.getStorage();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Get('ping')
|
@Get('ping')
|
||||||
@ApiOperation({ summary: 'Ping', description: 'Pong' })
|
@Endpoint({
|
||||||
|
summary: 'Ping',
|
||||||
|
description: 'Pong',
|
||||||
|
history: new HistoryBuilder().added('v1').beta('v1').stable('v2'),
|
||||||
|
})
|
||||||
pingServer(): ServerPingResponse {
|
pingServer(): ServerPingResponse {
|
||||||
return this.service.ping();
|
return this.service.ping();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Get('version')
|
@Get('version')
|
||||||
@ApiOperation({
|
@Endpoint({
|
||||||
summary: 'Get server version',
|
summary: 'Get server version',
|
||||||
description: 'Retrieve the current server version in semantic versioning (semver) format.',
|
description: 'Retrieve the current server version in semantic versioning (semver) format.',
|
||||||
|
history: new HistoryBuilder().added('v1').beta('v1').stable('v2'),
|
||||||
})
|
})
|
||||||
getServerVersion(): ServerVersionResponseDto {
|
getServerVersion(): ServerVersionResponseDto {
|
||||||
return this.versionService.getVersion();
|
return this.versionService.getVersion();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Get('version-history')
|
@Get('version-history')
|
||||||
@ApiOperation({
|
@Endpoint({
|
||||||
summary: 'Get version history',
|
summary: 'Get version history',
|
||||||
description: 'Retrieve a list of past versions the server has been on.',
|
description: 'Retrieve a list of past versions the server has been on.',
|
||||||
|
history: new HistoryBuilder().added('v1').beta('v1').stable('v2'),
|
||||||
})
|
})
|
||||||
getVersionHistory(): Promise<ServerVersionHistoryResponseDto[]> {
|
getVersionHistory(): Promise<ServerVersionHistoryResponseDto[]> {
|
||||||
return this.versionService.getVersionHistory();
|
return this.versionService.getVersionHistory();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Get('features')
|
@Get('features')
|
||||||
@ApiOperation({ summary: 'Get features', description: 'Retrieve available features supported by this server.' })
|
@Endpoint({
|
||||||
|
summary: 'Get features',
|
||||||
|
description: 'Retrieve available features supported by this server.',
|
||||||
|
history: new HistoryBuilder().added('v1').beta('v1').stable('v2'),
|
||||||
|
})
|
||||||
getServerFeatures(): Promise<ServerFeaturesDto> {
|
getServerFeatures(): Promise<ServerFeaturesDto> {
|
||||||
return this.service.getFeatures();
|
return this.service.getFeatures();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Get('theme')
|
@Get('theme')
|
||||||
@ApiOperation({ summary: 'Get theme', description: 'Retrieve the custom CSS, if existent.' })
|
@Endpoint({
|
||||||
|
summary: 'Get theme',
|
||||||
|
description: 'Retrieve the custom CSS, if existent.',
|
||||||
|
history: new HistoryBuilder().added('v1').beta('v1').stable('v2'),
|
||||||
|
})
|
||||||
getTheme(): Promise<ServerThemeDto> {
|
getTheme(): Promise<ServerThemeDto> {
|
||||||
return this.service.getTheme();
|
return this.service.getTheme();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Get('config')
|
@Get('config')
|
||||||
@ApiOperation({ summary: 'Get config', description: 'Retrieve the current server configuration.' })
|
@Endpoint({
|
||||||
|
summary: 'Get config',
|
||||||
|
description: 'Retrieve the current server configuration.',
|
||||||
|
history: new HistoryBuilder().added('v1').beta('v1').stable('v2'),
|
||||||
|
})
|
||||||
getServerConfig(): Promise<ServerConfigDto> {
|
getServerConfig(): Promise<ServerConfigDto> {
|
||||||
return this.service.getSystemConfig();
|
return this.service.getSystemConfig();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Get('statistics')
|
@Get('statistics')
|
||||||
@Authenticated({ permission: Permission.ServerStatistics, admin: true })
|
@Authenticated({ permission: Permission.ServerStatistics, admin: true })
|
||||||
@ApiOperation({
|
@Endpoint({
|
||||||
summary: 'Get statistics',
|
summary: 'Get statistics',
|
||||||
description: 'Retrieve statistics about the entire Immich instance such as asset counts.',
|
description: 'Retrieve statistics about the entire Immich instance such as asset counts.',
|
||||||
|
history: new HistoryBuilder().added('v1').beta('v1').stable('v2'),
|
||||||
})
|
})
|
||||||
getServerStatistics(): Promise<ServerStatsResponseDto> {
|
getServerStatistics(): Promise<ServerStatsResponseDto> {
|
||||||
return this.service.getStatistics();
|
return this.service.getStatistics();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Get('media-types')
|
@Get('media-types')
|
||||||
@ApiOperation({
|
@Endpoint({
|
||||||
summary: 'Get supported media types',
|
summary: 'Get supported media types',
|
||||||
description: 'Retrieve all media types supported by the server.',
|
description: 'Retrieve all media types supported by the server.',
|
||||||
|
history: new HistoryBuilder().added('v1').beta('v1').stable('v2'),
|
||||||
})
|
})
|
||||||
getSupportedMediaTypes(): ServerMediaTypesResponseDto {
|
getSupportedMediaTypes(): ServerMediaTypesResponseDto {
|
||||||
return this.service.getSupportedMediaTypes();
|
return this.service.getSupportedMediaTypes();
|
||||||
|
|
@ -118,9 +148,10 @@ export class ServerController {
|
||||||
@Get('license')
|
@Get('license')
|
||||||
@Authenticated({ permission: Permission.ServerLicenseRead, admin: true })
|
@Authenticated({ permission: Permission.ServerLicenseRead, admin: true })
|
||||||
@ApiNotFoundResponse()
|
@ApiNotFoundResponse()
|
||||||
@ApiOperation({
|
@Endpoint({
|
||||||
summary: 'Get product key',
|
summary: 'Get product key',
|
||||||
description: 'Retrieve information about whether the server currently has a product key registered.',
|
description: 'Retrieve information about whether the server currently has a product key registered.',
|
||||||
|
history: new HistoryBuilder().added('v1').beta('v1').stable('v2'),
|
||||||
})
|
})
|
||||||
getServerLicense(): Promise<LicenseResponseDto> {
|
getServerLicense(): Promise<LicenseResponseDto> {
|
||||||
return this.service.getLicense();
|
return this.service.getLicense();
|
||||||
|
|
@ -128,9 +159,10 @@ export class ServerController {
|
||||||
|
|
||||||
@Put('license')
|
@Put('license')
|
||||||
@Authenticated({ permission: Permission.ServerLicenseUpdate, admin: true })
|
@Authenticated({ permission: Permission.ServerLicenseUpdate, admin: true })
|
||||||
@ApiOperation({
|
@Endpoint({
|
||||||
summary: 'Set server product key',
|
summary: 'Set server product key',
|
||||||
description: 'Validate and set the server product key if successful.',
|
description: 'Validate and set the server product key if successful.',
|
||||||
|
history: new HistoryBuilder().added('v1').beta('v1').stable('v2'),
|
||||||
})
|
})
|
||||||
setServerLicense(@Body() license: LicenseKeyDto): Promise<LicenseResponseDto> {
|
setServerLicense(@Body() license: LicenseKeyDto): Promise<LicenseResponseDto> {
|
||||||
return this.service.setLicense(license);
|
return this.service.setLicense(license);
|
||||||
|
|
@ -139,16 +171,21 @@ export class ServerController {
|
||||||
@Delete('license')
|
@Delete('license')
|
||||||
@Authenticated({ permission: Permission.ServerLicenseDelete, admin: true })
|
@Authenticated({ permission: Permission.ServerLicenseDelete, admin: true })
|
||||||
@HttpCode(HttpStatus.NO_CONTENT)
|
@HttpCode(HttpStatus.NO_CONTENT)
|
||||||
@ApiOperation({ summary: 'Delete server product key', description: 'Delete the currently set server product key.' })
|
@Endpoint({
|
||||||
|
summary: 'Delete server product key',
|
||||||
|
description: 'Delete the currently set server product key.',
|
||||||
|
history: new HistoryBuilder().added('v1').beta('v1').stable('v2'),
|
||||||
|
})
|
||||||
deleteServerLicense(): Promise<void> {
|
deleteServerLicense(): Promise<void> {
|
||||||
return this.service.deleteLicense();
|
return this.service.deleteLicense();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Get('version-check')
|
@Get('version-check')
|
||||||
@Authenticated({ permission: Permission.ServerVersionCheck })
|
@Authenticated({ permission: Permission.ServerVersionCheck })
|
||||||
@ApiOperation({
|
@Endpoint({
|
||||||
summary: 'Get version check status',
|
summary: 'Get version check status',
|
||||||
description: 'Retrieve information about the last time the version check ran.',
|
description: 'Retrieve information about the last time the version check ran.',
|
||||||
|
history: new HistoryBuilder().added('v1').beta('v1').stable('v2'),
|
||||||
})
|
})
|
||||||
getVersionCheck(): Promise<VersionCheckStateResponseDto> {
|
getVersionCheck(): Promise<VersionCheckStateResponseDto> {
|
||||||
return this.systemMetadataService.getVersionCheckState();
|
return this.systemMetadataService.getVersionCheckState();
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,6 @@
|
||||||
import { Body, Controller, Delete, Get, HttpCode, HttpStatus, Param, Post, Put } from '@nestjs/common';
|
import { Body, Controller, Delete, Get, HttpCode, HttpStatus, Param, Post, Put } from '@nestjs/common';
|
||||||
import { ApiOperation, ApiTags } from '@nestjs/swagger';
|
import { ApiTags } from '@nestjs/swagger';
|
||||||
|
import { Endpoint, HistoryBuilder } from 'src/decorators';
|
||||||
import { AuthDto } from 'src/dtos/auth.dto';
|
import { AuthDto } from 'src/dtos/auth.dto';
|
||||||
import { SessionCreateDto, SessionCreateResponseDto, SessionResponseDto, SessionUpdateDto } from 'src/dtos/session.dto';
|
import { SessionCreateDto, SessionCreateResponseDto, SessionResponseDto, SessionUpdateDto } from 'src/dtos/session.dto';
|
||||||
import { ApiTag, Permission } from 'src/enum';
|
import { ApiTag, Permission } from 'src/enum';
|
||||||
|
|
@ -14,9 +15,10 @@ export class SessionController {
|
||||||
|
|
||||||
@Post()
|
@Post()
|
||||||
@Authenticated({ permission: Permission.SessionCreate })
|
@Authenticated({ permission: Permission.SessionCreate })
|
||||||
@ApiOperation({
|
@Endpoint({
|
||||||
summary: 'Create a session',
|
summary: 'Create a session',
|
||||||
description: 'Create a session as a child to the current session. This endpoint is used for casting.',
|
description: 'Create a session as a child to the current session. This endpoint is used for casting.',
|
||||||
|
history: new HistoryBuilder().added('v1').beta('v1').stable('v2'),
|
||||||
})
|
})
|
||||||
createSession(@Auth() auth: AuthDto, @Body() dto: SessionCreateDto): Promise<SessionCreateResponseDto> {
|
createSession(@Auth() auth: AuthDto, @Body() dto: SessionCreateDto): Promise<SessionCreateResponseDto> {
|
||||||
return this.service.create(auth, dto);
|
return this.service.create(auth, dto);
|
||||||
|
|
@ -24,9 +26,10 @@ export class SessionController {
|
||||||
|
|
||||||
@Get()
|
@Get()
|
||||||
@Authenticated({ permission: Permission.SessionRead })
|
@Authenticated({ permission: Permission.SessionRead })
|
||||||
@ApiOperation({
|
@Endpoint({
|
||||||
summary: 'Retrieve sessions',
|
summary: 'Retrieve sessions',
|
||||||
description: 'Retrieve a list of sessions for the user.',
|
description: 'Retrieve a list of sessions for the user.',
|
||||||
|
history: new HistoryBuilder().added('v1').beta('v1').stable('v2'),
|
||||||
})
|
})
|
||||||
getSessions(@Auth() auth: AuthDto): Promise<SessionResponseDto[]> {
|
getSessions(@Auth() auth: AuthDto): Promise<SessionResponseDto[]> {
|
||||||
return this.service.getAll(auth);
|
return this.service.getAll(auth);
|
||||||
|
|
@ -35,9 +38,10 @@ export class SessionController {
|
||||||
@Delete()
|
@Delete()
|
||||||
@Authenticated({ permission: Permission.SessionDelete })
|
@Authenticated({ permission: Permission.SessionDelete })
|
||||||
@HttpCode(HttpStatus.NO_CONTENT)
|
@HttpCode(HttpStatus.NO_CONTENT)
|
||||||
@ApiOperation({
|
@Endpoint({
|
||||||
summary: 'Delete all sessions',
|
summary: 'Delete all sessions',
|
||||||
description: 'Delete all sessions for the user. This will not delete the current session.',
|
description: 'Delete all sessions for the user. This will not delete the current session.',
|
||||||
|
history: new HistoryBuilder().added('v1').beta('v1').stable('v2'),
|
||||||
})
|
})
|
||||||
deleteAllSessions(@Auth() auth: AuthDto): Promise<void> {
|
deleteAllSessions(@Auth() auth: AuthDto): Promise<void> {
|
||||||
return this.service.deleteAll(auth);
|
return this.service.deleteAll(auth);
|
||||||
|
|
@ -45,9 +49,10 @@ export class SessionController {
|
||||||
|
|
||||||
@Put(':id')
|
@Put(':id')
|
||||||
@Authenticated({ permission: Permission.SessionUpdate })
|
@Authenticated({ permission: Permission.SessionUpdate })
|
||||||
@ApiOperation({
|
@Endpoint({
|
||||||
summary: 'Update a session',
|
summary: 'Update a session',
|
||||||
description: 'Update a specific session identified by id.',
|
description: 'Update a specific session identified by id.',
|
||||||
|
history: new HistoryBuilder().added('v1').beta('v1').stable('v2'),
|
||||||
})
|
})
|
||||||
updateSession(
|
updateSession(
|
||||||
@Auth() auth: AuthDto,
|
@Auth() auth: AuthDto,
|
||||||
|
|
@ -60,9 +65,10 @@ export class SessionController {
|
||||||
@Delete(':id')
|
@Delete(':id')
|
||||||
@Authenticated({ permission: Permission.SessionDelete })
|
@Authenticated({ permission: Permission.SessionDelete })
|
||||||
@HttpCode(HttpStatus.NO_CONTENT)
|
@HttpCode(HttpStatus.NO_CONTENT)
|
||||||
@ApiOperation({
|
@Endpoint({
|
||||||
summary: 'Delete a session',
|
summary: 'Delete a session',
|
||||||
description: 'Delete a specific session by id.',
|
description: 'Delete a specific session by id.',
|
||||||
|
history: new HistoryBuilder().added('v1').beta('v1').stable('v2'),
|
||||||
})
|
})
|
||||||
deleteSession(@Auth() auth: AuthDto, @Param() { id }: UUIDParamDto): Promise<void> {
|
deleteSession(@Auth() auth: AuthDto, @Param() { id }: UUIDParamDto): Promise<void> {
|
||||||
return this.service.delete(auth, id);
|
return this.service.delete(auth, id);
|
||||||
|
|
@ -71,9 +77,10 @@ export class SessionController {
|
||||||
@Post(':id/lock')
|
@Post(':id/lock')
|
||||||
@Authenticated({ permission: Permission.SessionLock })
|
@Authenticated({ permission: Permission.SessionLock })
|
||||||
@HttpCode(HttpStatus.NO_CONTENT)
|
@HttpCode(HttpStatus.NO_CONTENT)
|
||||||
@ApiOperation({
|
@Endpoint({
|
||||||
summary: 'Lock a session',
|
summary: 'Lock a session',
|
||||||
description: 'Lock a specific session by id.',
|
description: 'Lock a specific session by id.',
|
||||||
|
history: new HistoryBuilder().added('v1').beta('v1').stable('v2'),
|
||||||
})
|
})
|
||||||
lockSession(@Auth() auth: AuthDto, @Param() { id }: UUIDParamDto): Promise<void> {
|
lockSession(@Auth() auth: AuthDto, @Param() { id }: UUIDParamDto): Promise<void> {
|
||||||
return this.service.lock(auth, id);
|
return this.service.lock(auth, id);
|
||||||
|
|
|
||||||
|
|
@ -13,8 +13,9 @@ import {
|
||||||
Req,
|
Req,
|
||||||
Res,
|
Res,
|
||||||
} from '@nestjs/common';
|
} from '@nestjs/common';
|
||||||
import { ApiOperation, ApiTags } from '@nestjs/swagger';
|
import { ApiTags } from '@nestjs/swagger';
|
||||||
import { Request, Response } from 'express';
|
import { Request, Response } from 'express';
|
||||||
|
import { Endpoint, HistoryBuilder } from 'src/decorators';
|
||||||
import { AssetIdsResponseDto } from 'src/dtos/asset-ids.response.dto';
|
import { AssetIdsResponseDto } from 'src/dtos/asset-ids.response.dto';
|
||||||
import { AssetIdsDto } from 'src/dtos/asset.dto';
|
import { AssetIdsDto } from 'src/dtos/asset.dto';
|
||||||
import { AuthDto } from 'src/dtos/auth.dto';
|
import { AuthDto } from 'src/dtos/auth.dto';
|
||||||
|
|
@ -39,9 +40,10 @@ export class SharedLinkController {
|
||||||
|
|
||||||
@Get()
|
@Get()
|
||||||
@Authenticated({ permission: Permission.SharedLinkRead })
|
@Authenticated({ permission: Permission.SharedLinkRead })
|
||||||
@ApiOperation({
|
@Endpoint({
|
||||||
summary: 'Retrieve all shared links',
|
summary: 'Retrieve all shared links',
|
||||||
description: 'Retrieve a list of all shared links.',
|
description: 'Retrieve a list of all shared links.',
|
||||||
|
history: new HistoryBuilder().added('v1').beta('v1').stable('v2'),
|
||||||
})
|
})
|
||||||
getAllSharedLinks(@Auth() auth: AuthDto, @Query() dto: SharedLinkSearchDto): Promise<SharedLinkResponseDto[]> {
|
getAllSharedLinks(@Auth() auth: AuthDto, @Query() dto: SharedLinkSearchDto): Promise<SharedLinkResponseDto[]> {
|
||||||
return this.service.getAll(auth, dto);
|
return this.service.getAll(auth, dto);
|
||||||
|
|
@ -49,9 +51,10 @@ export class SharedLinkController {
|
||||||
|
|
||||||
@Get('me')
|
@Get('me')
|
||||||
@Authenticated({ sharedLink: true })
|
@Authenticated({ sharedLink: true })
|
||||||
@ApiOperation({
|
@Endpoint({
|
||||||
summary: 'Retrieve current shared link',
|
summary: 'Retrieve current shared link',
|
||||||
description: 'Retrieve the current shared link associated with authentication method.',
|
description: 'Retrieve the current shared link associated with authentication method.',
|
||||||
|
history: new HistoryBuilder().added('v1').beta('v1').stable('v2'),
|
||||||
})
|
})
|
||||||
async getMySharedLink(
|
async getMySharedLink(
|
||||||
@Auth() auth: AuthDto,
|
@Auth() auth: AuthDto,
|
||||||
|
|
@ -73,9 +76,10 @@ export class SharedLinkController {
|
||||||
|
|
||||||
@Get(':id')
|
@Get(':id')
|
||||||
@Authenticated({ permission: Permission.SharedLinkRead })
|
@Authenticated({ permission: Permission.SharedLinkRead })
|
||||||
@ApiOperation({
|
@Endpoint({
|
||||||
summary: 'Retrieve a shared link',
|
summary: 'Retrieve a shared link',
|
||||||
description: 'Retrieve a specific shared link by its ID.',
|
description: 'Retrieve a specific shared link by its ID.',
|
||||||
|
history: new HistoryBuilder().added('v1').beta('v1').stable('v2'),
|
||||||
})
|
})
|
||||||
getSharedLinkById(@Auth() auth: AuthDto, @Param() { id }: UUIDParamDto): Promise<SharedLinkResponseDto> {
|
getSharedLinkById(@Auth() auth: AuthDto, @Param() { id }: UUIDParamDto): Promise<SharedLinkResponseDto> {
|
||||||
return this.service.get(auth, id);
|
return this.service.get(auth, id);
|
||||||
|
|
@ -83,9 +87,10 @@ export class SharedLinkController {
|
||||||
|
|
||||||
@Post()
|
@Post()
|
||||||
@Authenticated({ permission: Permission.SharedLinkCreate })
|
@Authenticated({ permission: Permission.SharedLinkCreate })
|
||||||
@ApiOperation({
|
@Endpoint({
|
||||||
summary: 'Create a shared link',
|
summary: 'Create a shared link',
|
||||||
description: 'Create a new shared link.',
|
description: 'Create a new shared link.',
|
||||||
|
history: new HistoryBuilder().added('v1').beta('v1').stable('v2'),
|
||||||
})
|
})
|
||||||
createSharedLink(@Auth() auth: AuthDto, @Body() dto: SharedLinkCreateDto) {
|
createSharedLink(@Auth() auth: AuthDto, @Body() dto: SharedLinkCreateDto) {
|
||||||
return this.service.create(auth, dto);
|
return this.service.create(auth, dto);
|
||||||
|
|
@ -93,9 +98,10 @@ export class SharedLinkController {
|
||||||
|
|
||||||
@Patch(':id')
|
@Patch(':id')
|
||||||
@Authenticated({ permission: Permission.SharedLinkUpdate })
|
@Authenticated({ permission: Permission.SharedLinkUpdate })
|
||||||
@ApiOperation({
|
@Endpoint({
|
||||||
summary: 'Update a shared link',
|
summary: 'Update a shared link',
|
||||||
description: 'Update an existing shared link by its ID.',
|
description: 'Update an existing shared link by its ID.',
|
||||||
|
history: new HistoryBuilder().added('v1').beta('v1').stable('v2'),
|
||||||
})
|
})
|
||||||
updateSharedLink(
|
updateSharedLink(
|
||||||
@Auth() auth: AuthDto,
|
@Auth() auth: AuthDto,
|
||||||
|
|
@ -108,9 +114,10 @@ export class SharedLinkController {
|
||||||
@Delete(':id')
|
@Delete(':id')
|
||||||
@Authenticated({ permission: Permission.SharedLinkDelete })
|
@Authenticated({ permission: Permission.SharedLinkDelete })
|
||||||
@HttpCode(HttpStatus.NO_CONTENT)
|
@HttpCode(HttpStatus.NO_CONTENT)
|
||||||
@ApiOperation({
|
@Endpoint({
|
||||||
summary: 'Delete a shared link',
|
summary: 'Delete a shared link',
|
||||||
description: 'Delete a specific shared link by its ID.',
|
description: 'Delete a specific shared link by its ID.',
|
||||||
|
history: new HistoryBuilder().added('v1').beta('v1').stable('v2'),
|
||||||
})
|
})
|
||||||
removeSharedLink(@Auth() auth: AuthDto, @Param() { id }: UUIDParamDto): Promise<void> {
|
removeSharedLink(@Auth() auth: AuthDto, @Param() { id }: UUIDParamDto): Promise<void> {
|
||||||
return this.service.remove(auth, id);
|
return this.service.remove(auth, id);
|
||||||
|
|
@ -118,10 +125,11 @@ export class SharedLinkController {
|
||||||
|
|
||||||
@Put(':id/assets')
|
@Put(':id/assets')
|
||||||
@Authenticated({ sharedLink: true })
|
@Authenticated({ sharedLink: true })
|
||||||
@ApiOperation({
|
@Endpoint({
|
||||||
summary: 'Add assets to a shared link',
|
summary: 'Add assets to a shared link',
|
||||||
description:
|
description:
|
||||||
'Add assets to a specific shared link by its ID. This endpoint is only relevant for shared link of type individual.',
|
'Add assets to a specific shared link by its ID. This endpoint is only relevant for shared link of type individual.',
|
||||||
|
history: new HistoryBuilder().added('v1').beta('v1').stable('v2'),
|
||||||
})
|
})
|
||||||
addSharedLinkAssets(
|
addSharedLinkAssets(
|
||||||
@Auth() auth: AuthDto,
|
@Auth() auth: AuthDto,
|
||||||
|
|
@ -133,10 +141,11 @@ export class SharedLinkController {
|
||||||
|
|
||||||
@Delete(':id/assets')
|
@Delete(':id/assets')
|
||||||
@Authenticated({ sharedLink: true })
|
@Authenticated({ sharedLink: true })
|
||||||
@ApiOperation({
|
@Endpoint({
|
||||||
summary: 'Remove assets from a shared link',
|
summary: 'Remove assets from a shared link',
|
||||||
description:
|
description:
|
||||||
'Remove assets from a specific shared link by its ID. This endpoint is only relevant for shared link of type individual.',
|
'Remove assets from a specific shared link by its ID. This endpoint is only relevant for shared link of type individual.',
|
||||||
|
history: new HistoryBuilder().added('v1').beta('v1').stable('v2'),
|
||||||
})
|
})
|
||||||
removeSharedLinkAssets(
|
removeSharedLinkAssets(
|
||||||
@Auth() auth: AuthDto,
|
@Auth() auth: AuthDto,
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,6 @@
|
||||||
import { Body, Controller, Delete, Get, HttpCode, HttpStatus, Param, Post, Put, Query } from '@nestjs/common';
|
import { Body, Controller, Delete, Get, HttpCode, HttpStatus, Param, Post, Put, Query } from '@nestjs/common';
|
||||||
import { ApiOperation, ApiTags } from '@nestjs/swagger';
|
import { ApiTags } from '@nestjs/swagger';
|
||||||
|
import { Endpoint, HistoryBuilder } from 'src/decorators';
|
||||||
import { BulkIdsDto } from 'src/dtos/asset-ids.response.dto';
|
import { BulkIdsDto } from 'src/dtos/asset-ids.response.dto';
|
||||||
import { AuthDto } from 'src/dtos/auth.dto';
|
import { AuthDto } from 'src/dtos/auth.dto';
|
||||||
import { StackCreateDto, StackResponseDto, StackSearchDto, StackUpdateDto } from 'src/dtos/stack.dto';
|
import { StackCreateDto, StackResponseDto, StackSearchDto, StackUpdateDto } from 'src/dtos/stack.dto';
|
||||||
|
|
@ -15,9 +16,10 @@ export class StackController {
|
||||||
|
|
||||||
@Get()
|
@Get()
|
||||||
@Authenticated({ permission: Permission.StackRead })
|
@Authenticated({ permission: Permission.StackRead })
|
||||||
@ApiOperation({
|
@Endpoint({
|
||||||
summary: 'Retrieve stacks',
|
summary: 'Retrieve stacks',
|
||||||
description: 'Retrieve a list of stacks.',
|
description: 'Retrieve a list of stacks.',
|
||||||
|
history: new HistoryBuilder().added('v1').beta('v1').stable('v2'),
|
||||||
})
|
})
|
||||||
searchStacks(@Auth() auth: AuthDto, @Query() query: StackSearchDto): Promise<StackResponseDto[]> {
|
searchStacks(@Auth() auth: AuthDto, @Query() query: StackSearchDto): Promise<StackResponseDto[]> {
|
||||||
return this.service.search(auth, query);
|
return this.service.search(auth, query);
|
||||||
|
|
@ -25,10 +27,11 @@ export class StackController {
|
||||||
|
|
||||||
@Post()
|
@Post()
|
||||||
@Authenticated({ permission: Permission.StackCreate })
|
@Authenticated({ permission: Permission.StackCreate })
|
||||||
@ApiOperation({
|
@Endpoint({
|
||||||
summary: 'Create a stack',
|
summary: 'Create a stack',
|
||||||
description:
|
description:
|
||||||
'Create a new stack by providing a name and a list of asset IDs to include in the stack. If any of the provided asset IDs are primary assets of an existing stack, the existing stack will be merged into the newly created stack.',
|
'Create a new stack by providing a name and a list of asset IDs to include in the stack. If any of the provided asset IDs are primary assets of an existing stack, the existing stack will be merged into the newly created stack.',
|
||||||
|
history: new HistoryBuilder().added('v1').beta('v1').stable('v2'),
|
||||||
})
|
})
|
||||||
createStack(@Auth() auth: AuthDto, @Body() dto: StackCreateDto): Promise<StackResponseDto> {
|
createStack(@Auth() auth: AuthDto, @Body() dto: StackCreateDto): Promise<StackResponseDto> {
|
||||||
return this.service.create(auth, dto);
|
return this.service.create(auth, dto);
|
||||||
|
|
@ -37,9 +40,10 @@ export class StackController {
|
||||||
@Delete()
|
@Delete()
|
||||||
@Authenticated({ permission: Permission.StackDelete })
|
@Authenticated({ permission: Permission.StackDelete })
|
||||||
@HttpCode(HttpStatus.NO_CONTENT)
|
@HttpCode(HttpStatus.NO_CONTENT)
|
||||||
@ApiOperation({
|
@Endpoint({
|
||||||
summary: 'Delete stacks',
|
summary: 'Delete stacks',
|
||||||
description: 'Delete multiple stacks by providing a list of stack IDs.',
|
description: 'Delete multiple stacks by providing a list of stack IDs.',
|
||||||
|
history: new HistoryBuilder().added('v1').beta('v1').stable('v2'),
|
||||||
})
|
})
|
||||||
deleteStacks(@Auth() auth: AuthDto, @Body() dto: BulkIdsDto): Promise<void> {
|
deleteStacks(@Auth() auth: AuthDto, @Body() dto: BulkIdsDto): Promise<void> {
|
||||||
return this.service.deleteAll(auth, dto);
|
return this.service.deleteAll(auth, dto);
|
||||||
|
|
@ -47,9 +51,10 @@ export class StackController {
|
||||||
|
|
||||||
@Get(':id')
|
@Get(':id')
|
||||||
@Authenticated({ permission: Permission.StackRead })
|
@Authenticated({ permission: Permission.StackRead })
|
||||||
@ApiOperation({
|
@Endpoint({
|
||||||
summary: 'Retrieve a stack',
|
summary: 'Retrieve a stack',
|
||||||
description: 'Retrieve a specific stack by its ID.',
|
description: 'Retrieve a specific stack by its ID.',
|
||||||
|
history: new HistoryBuilder().added('v1').beta('v1').stable('v2'),
|
||||||
})
|
})
|
||||||
getStack(@Auth() auth: AuthDto, @Param() { id }: UUIDParamDto): Promise<StackResponseDto> {
|
getStack(@Auth() auth: AuthDto, @Param() { id }: UUIDParamDto): Promise<StackResponseDto> {
|
||||||
return this.service.get(auth, id);
|
return this.service.get(auth, id);
|
||||||
|
|
@ -57,9 +62,10 @@ export class StackController {
|
||||||
|
|
||||||
@Put(':id')
|
@Put(':id')
|
||||||
@Authenticated({ permission: Permission.StackUpdate })
|
@Authenticated({ permission: Permission.StackUpdate })
|
||||||
@ApiOperation({
|
@Endpoint({
|
||||||
summary: 'Update a stack',
|
summary: 'Update a stack',
|
||||||
description: 'Update an existing stack by its ID.',
|
description: 'Update an existing stack by its ID.',
|
||||||
|
history: new HistoryBuilder().added('v1').beta('v1').stable('v2'),
|
||||||
})
|
})
|
||||||
updateStack(
|
updateStack(
|
||||||
@Auth() auth: AuthDto,
|
@Auth() auth: AuthDto,
|
||||||
|
|
@ -72,9 +78,10 @@ export class StackController {
|
||||||
@Delete(':id')
|
@Delete(':id')
|
||||||
@Authenticated({ permission: Permission.StackDelete })
|
@Authenticated({ permission: Permission.StackDelete })
|
||||||
@HttpCode(HttpStatus.NO_CONTENT)
|
@HttpCode(HttpStatus.NO_CONTENT)
|
||||||
@ApiOperation({
|
@Endpoint({
|
||||||
summary: 'Delete a stack',
|
summary: 'Delete a stack',
|
||||||
description: 'Delete a specific stack by its ID.',
|
description: 'Delete a specific stack by its ID.',
|
||||||
|
history: new HistoryBuilder().added('v1').beta('v1').stable('v2'),
|
||||||
})
|
})
|
||||||
deleteStack(@Auth() auth: AuthDto, @Param() { id }: UUIDParamDto): Promise<void> {
|
deleteStack(@Auth() auth: AuthDto, @Param() { id }: UUIDParamDto): Promise<void> {
|
||||||
return this.service.delete(auth, id);
|
return this.service.delete(auth, id);
|
||||||
|
|
@ -83,9 +90,10 @@ export class StackController {
|
||||||
@Delete(':id/assets/:assetId')
|
@Delete(':id/assets/:assetId')
|
||||||
@Authenticated({ permission: Permission.StackUpdate })
|
@Authenticated({ permission: Permission.StackUpdate })
|
||||||
@HttpCode(HttpStatus.NO_CONTENT)
|
@HttpCode(HttpStatus.NO_CONTENT)
|
||||||
@ApiOperation({
|
@Endpoint({
|
||||||
summary: 'Remove an asset from a stack',
|
summary: 'Remove an asset from a stack',
|
||||||
description: 'Remove a specific asset from a stack by providing the stack ID and asset ID.',
|
description: 'Remove a specific asset from a stack by providing the stack ID and asset ID.',
|
||||||
|
history: new HistoryBuilder().added('v1').beta('v1').stable('v2'),
|
||||||
})
|
})
|
||||||
removeAssetFromStack(@Auth() auth: AuthDto, @Param() dto: UUIDAssetIDParamDto): Promise<void> {
|
removeAssetFromStack(@Auth() auth: AuthDto, @Param() dto: UUIDAssetIDParamDto): Promise<void> {
|
||||||
return this.service.removeAsset(auth, dto);
|
return this.service.removeAsset(auth, dto);
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
import { Body, Controller, Delete, Get, Header, HttpCode, HttpStatus, Post, Res } from '@nestjs/common';
|
import { Body, Controller, Delete, Get, Header, HttpCode, HttpStatus, Post, Res } from '@nestjs/common';
|
||||||
import { ApiOperation, ApiTags } from '@nestjs/swagger';
|
import { ApiTags } from '@nestjs/swagger';
|
||||||
import { Response } from 'express';
|
import { Response } from 'express';
|
||||||
import { EndpointLifecycle } from 'src/decorators';
|
import { Endpoint, HistoryBuilder } from 'src/decorators';
|
||||||
import { AssetResponseDto } from 'src/dtos/asset-response.dto';
|
import { AssetResponseDto } from 'src/dtos/asset-response.dto';
|
||||||
import { AuthDto } from 'src/dtos/auth.dto';
|
import { AuthDto } from 'src/dtos/auth.dto';
|
||||||
import {
|
import {
|
||||||
|
|
@ -29,10 +29,10 @@ export class SyncController {
|
||||||
@Post('full-sync')
|
@Post('full-sync')
|
||||||
@Authenticated()
|
@Authenticated()
|
||||||
@HttpCode(HttpStatus.OK)
|
@HttpCode(HttpStatus.OK)
|
||||||
@EndpointLifecycle({
|
@Endpoint({
|
||||||
deprecatedAt: 'v2.0.0',
|
|
||||||
summary: 'Get full sync for user',
|
summary: 'Get full sync for user',
|
||||||
description: 'Retrieve all assets for a full synchronization for the authenticated user.',
|
description: 'Retrieve all assets for a full synchronization for the authenticated user.',
|
||||||
|
history: new HistoryBuilder().added('v1').deprecated('v2'),
|
||||||
})
|
})
|
||||||
getFullSyncForUser(@Auth() auth: AuthDto, @Body() dto: AssetFullSyncDto): Promise<AssetResponseDto[]> {
|
getFullSyncForUser(@Auth() auth: AuthDto, @Body() dto: AssetFullSyncDto): Promise<AssetResponseDto[]> {
|
||||||
return this.service.getFullSync(auth, dto);
|
return this.service.getFullSync(auth, dto);
|
||||||
|
|
@ -41,10 +41,10 @@ export class SyncController {
|
||||||
@Post('delta-sync')
|
@Post('delta-sync')
|
||||||
@Authenticated()
|
@Authenticated()
|
||||||
@HttpCode(HttpStatus.OK)
|
@HttpCode(HttpStatus.OK)
|
||||||
@EndpointLifecycle({
|
@Endpoint({
|
||||||
deprecatedAt: 'v2.0.0',
|
|
||||||
summary: 'Get delta sync for user',
|
summary: 'Get delta sync for user',
|
||||||
description: 'Retrieve changed assets since the last sync for the authenticated user.',
|
description: 'Retrieve changed assets since the last sync for the authenticated user.',
|
||||||
|
history: new HistoryBuilder().added('v1').deprecated('v2'),
|
||||||
})
|
})
|
||||||
getDeltaSync(@Auth() auth: AuthDto, @Body() dto: AssetDeltaSyncDto): Promise<AssetDeltaSyncResponseDto> {
|
getDeltaSync(@Auth() auth: AuthDto, @Body() dto: AssetDeltaSyncDto): Promise<AssetDeltaSyncResponseDto> {
|
||||||
return this.service.getDeltaSync(auth, dto);
|
return this.service.getDeltaSync(auth, dto);
|
||||||
|
|
@ -54,10 +54,11 @@ export class SyncController {
|
||||||
@Authenticated({ permission: Permission.SyncStream })
|
@Authenticated({ permission: Permission.SyncStream })
|
||||||
@Header('Content-Type', 'application/jsonlines+json')
|
@Header('Content-Type', 'application/jsonlines+json')
|
||||||
@HttpCode(HttpStatus.OK)
|
@HttpCode(HttpStatus.OK)
|
||||||
@ApiOperation({
|
@Endpoint({
|
||||||
summary: 'Stream sync changes',
|
summary: 'Stream sync changes',
|
||||||
description:
|
description:
|
||||||
'Retrieve a JSON lines streamed response of changes for synchronization. This endpoint is used by the mobile app to efficiently stay up to date with changes.',
|
'Retrieve a JSON lines streamed response of changes for synchronization. This endpoint is used by the mobile app to efficiently stay up to date with changes.',
|
||||||
|
history: new HistoryBuilder().added('v1').beta('v1').stable('v2'),
|
||||||
})
|
})
|
||||||
async getSyncStream(@Auth() auth: AuthDto, @Res() res: Response, @Body() dto: SyncStreamDto) {
|
async getSyncStream(@Auth() auth: AuthDto, @Res() res: Response, @Body() dto: SyncStreamDto) {
|
||||||
try {
|
try {
|
||||||
|
|
@ -70,9 +71,10 @@ export class SyncController {
|
||||||
|
|
||||||
@Get('ack')
|
@Get('ack')
|
||||||
@Authenticated({ permission: Permission.SyncCheckpointRead })
|
@Authenticated({ permission: Permission.SyncCheckpointRead })
|
||||||
@ApiOperation({
|
@Endpoint({
|
||||||
summary: 'Retrieve acknowledgements',
|
summary: 'Retrieve acknowledgements',
|
||||||
description: 'Retrieve the synchronization acknowledgments for the current session.',
|
description: 'Retrieve the synchronization acknowledgments for the current session.',
|
||||||
|
history: new HistoryBuilder().added('v1').beta('v1').stable('v2'),
|
||||||
})
|
})
|
||||||
getSyncAck(@Auth() auth: AuthDto): Promise<SyncAckDto[]> {
|
getSyncAck(@Auth() auth: AuthDto): Promise<SyncAckDto[]> {
|
||||||
return this.service.getAcks(auth);
|
return this.service.getAcks(auth);
|
||||||
|
|
@ -81,10 +83,11 @@ export class SyncController {
|
||||||
@Post('ack')
|
@Post('ack')
|
||||||
@Authenticated({ permission: Permission.SyncCheckpointUpdate })
|
@Authenticated({ permission: Permission.SyncCheckpointUpdate })
|
||||||
@HttpCode(HttpStatus.NO_CONTENT)
|
@HttpCode(HttpStatus.NO_CONTENT)
|
||||||
@ApiOperation({
|
@Endpoint({
|
||||||
summary: 'Acknowledge changes',
|
summary: 'Acknowledge changes',
|
||||||
description:
|
description:
|
||||||
'Send a list of synchronization acknowledgements to confirm that the latest changes have been received.',
|
'Send a list of synchronization acknowledgements to confirm that the latest changes have been received.',
|
||||||
|
history: new HistoryBuilder().added('v1').beta('v1').stable('v2'),
|
||||||
})
|
})
|
||||||
sendSyncAck(@Auth() auth: AuthDto, @Body() dto: SyncAckSetDto) {
|
sendSyncAck(@Auth() auth: AuthDto, @Body() dto: SyncAckSetDto) {
|
||||||
return this.service.setAcks(auth, dto);
|
return this.service.setAcks(auth, dto);
|
||||||
|
|
@ -93,9 +96,10 @@ export class SyncController {
|
||||||
@Delete('ack')
|
@Delete('ack')
|
||||||
@Authenticated({ permission: Permission.SyncCheckpointDelete })
|
@Authenticated({ permission: Permission.SyncCheckpointDelete })
|
||||||
@HttpCode(HttpStatus.NO_CONTENT)
|
@HttpCode(HttpStatus.NO_CONTENT)
|
||||||
@ApiOperation({
|
@Endpoint({
|
||||||
summary: 'Delete acknowledgements',
|
summary: 'Delete acknowledgements',
|
||||||
description: 'Delete specific synchronization acknowledgments.',
|
description: 'Delete specific synchronization acknowledgments.',
|
||||||
|
history: new HistoryBuilder().added('v1').beta('v1').stable('v2'),
|
||||||
})
|
})
|
||||||
deleteSyncAck(@Auth() auth: AuthDto, @Body() dto: SyncAckDeleteDto): Promise<void> {
|
deleteSyncAck(@Auth() auth: AuthDto, @Body() dto: SyncAckDeleteDto): Promise<void> {
|
||||||
return this.service.deleteAcks(auth, dto);
|
return this.service.deleteAcks(auth, dto);
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,6 @@
|
||||||
import { Body, Controller, Get, Put } from '@nestjs/common';
|
import { Body, Controller, Get, Put } from '@nestjs/common';
|
||||||
import { ApiOperation, ApiTags } from '@nestjs/swagger';
|
import { ApiTags } from '@nestjs/swagger';
|
||||||
|
import { Endpoint, HistoryBuilder } from 'src/decorators';
|
||||||
import { SystemConfigDto, SystemConfigTemplateStorageOptionDto } from 'src/dtos/system-config.dto';
|
import { SystemConfigDto, SystemConfigTemplateStorageOptionDto } from 'src/dtos/system-config.dto';
|
||||||
import { ApiTag, Permission } from 'src/enum';
|
import { ApiTag, Permission } from 'src/enum';
|
||||||
import { Authenticated } from 'src/middleware/auth.guard';
|
import { Authenticated } from 'src/middleware/auth.guard';
|
||||||
|
|
@ -16,16 +17,21 @@ export class SystemConfigController {
|
||||||
|
|
||||||
@Get()
|
@Get()
|
||||||
@Authenticated({ permission: Permission.SystemConfigRead, admin: true })
|
@Authenticated({ permission: Permission.SystemConfigRead, admin: true })
|
||||||
@ApiOperation({ summary: 'Get system configuration', description: 'Retrieve the current system configuration.' })
|
@Endpoint({
|
||||||
|
summary: 'Get system configuration',
|
||||||
|
description: 'Retrieve the current system configuration.',
|
||||||
|
history: new HistoryBuilder().added('v1').beta('v1').stable('v2'),
|
||||||
|
})
|
||||||
getConfig(): Promise<SystemConfigDto> {
|
getConfig(): Promise<SystemConfigDto> {
|
||||||
return this.service.getSystemConfig();
|
return this.service.getSystemConfig();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Get('defaults')
|
@Get('defaults')
|
||||||
@Authenticated({ permission: Permission.SystemConfigRead, admin: true })
|
@Authenticated({ permission: Permission.SystemConfigRead, admin: true })
|
||||||
@ApiOperation({
|
@Endpoint({
|
||||||
summary: 'Get system configuration defaults',
|
summary: 'Get system configuration defaults',
|
||||||
description: 'Retrieve the default values for the system configuration.',
|
description: 'Retrieve the default values for the system configuration.',
|
||||||
|
history: new HistoryBuilder().added('v1').beta('v1').stable('v2'),
|
||||||
})
|
})
|
||||||
getConfigDefaults(): SystemConfigDto {
|
getConfigDefaults(): SystemConfigDto {
|
||||||
return this.service.getDefaults();
|
return this.service.getDefaults();
|
||||||
|
|
@ -33,9 +39,10 @@ export class SystemConfigController {
|
||||||
|
|
||||||
@Put()
|
@Put()
|
||||||
@Authenticated({ permission: Permission.SystemConfigUpdate, admin: true })
|
@Authenticated({ permission: Permission.SystemConfigUpdate, admin: true })
|
||||||
@ApiOperation({
|
@Endpoint({
|
||||||
summary: 'Update system configuration',
|
summary: 'Update system configuration',
|
||||||
description: 'Update the system configuration with a new system configuration.',
|
description: 'Update the system configuration with a new system configuration.',
|
||||||
|
history: new HistoryBuilder().added('v1').beta('v1').stable('v2'),
|
||||||
})
|
})
|
||||||
updateConfig(@Body() dto: SystemConfigDto): Promise<SystemConfigDto> {
|
updateConfig(@Body() dto: SystemConfigDto): Promise<SystemConfigDto> {
|
||||||
return this.service.updateSystemConfig(dto);
|
return this.service.updateSystemConfig(dto);
|
||||||
|
|
@ -43,9 +50,10 @@ export class SystemConfigController {
|
||||||
|
|
||||||
@Get('storage-template-options')
|
@Get('storage-template-options')
|
||||||
@Authenticated({ permission: Permission.SystemConfigRead, admin: true })
|
@Authenticated({ permission: Permission.SystemConfigRead, admin: true })
|
||||||
@ApiOperation({
|
@Endpoint({
|
||||||
summary: 'Get storage template options',
|
summary: 'Get storage template options',
|
||||||
description: 'Retrieve exemplary storage template options.',
|
description: 'Retrieve exemplary storage template options.',
|
||||||
|
history: new HistoryBuilder().added('v1').beta('v1').stable('v2'),
|
||||||
})
|
})
|
||||||
getStorageTemplateOptions(): SystemConfigTemplateStorageOptionDto {
|
getStorageTemplateOptions(): SystemConfigTemplateStorageOptionDto {
|
||||||
return this.storageTemplateService.getStorageTemplateOptions();
|
return this.storageTemplateService.getStorageTemplateOptions();
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,6 @@
|
||||||
import { Body, Controller, Get, HttpCode, HttpStatus, Post } from '@nestjs/common';
|
import { Body, Controller, Get, HttpCode, HttpStatus, Post } from '@nestjs/common';
|
||||||
import { ApiOperation, ApiTags } from '@nestjs/swagger';
|
import { ApiTags } from '@nestjs/swagger';
|
||||||
|
import { Endpoint, HistoryBuilder } from 'src/decorators';
|
||||||
import {
|
import {
|
||||||
AdminOnboardingUpdateDto,
|
AdminOnboardingUpdateDto,
|
||||||
ReverseGeocodingStateResponseDto,
|
ReverseGeocodingStateResponseDto,
|
||||||
|
|
@ -16,9 +17,10 @@ export class SystemMetadataController {
|
||||||
|
|
||||||
@Get('admin-onboarding')
|
@Get('admin-onboarding')
|
||||||
@Authenticated({ permission: Permission.SystemMetadataRead, admin: true })
|
@Authenticated({ permission: Permission.SystemMetadataRead, admin: true })
|
||||||
@ApiOperation({
|
@Endpoint({
|
||||||
summary: 'Retrieve admin onboarding',
|
summary: 'Retrieve admin onboarding',
|
||||||
description: 'Retrieve the current admin onboarding status.',
|
description: 'Retrieve the current admin onboarding status.',
|
||||||
|
history: new HistoryBuilder().added('v1').beta('v1').stable('v2'),
|
||||||
})
|
})
|
||||||
getAdminOnboarding(): Promise<AdminOnboardingUpdateDto> {
|
getAdminOnboarding(): Promise<AdminOnboardingUpdateDto> {
|
||||||
return this.service.getAdminOnboarding();
|
return this.service.getAdminOnboarding();
|
||||||
|
|
@ -27,9 +29,10 @@ export class SystemMetadataController {
|
||||||
@Post('admin-onboarding')
|
@Post('admin-onboarding')
|
||||||
@Authenticated({ permission: Permission.SystemMetadataUpdate, admin: true })
|
@Authenticated({ permission: Permission.SystemMetadataUpdate, admin: true })
|
||||||
@HttpCode(HttpStatus.NO_CONTENT)
|
@HttpCode(HttpStatus.NO_CONTENT)
|
||||||
@ApiOperation({
|
@Endpoint({
|
||||||
summary: 'Update admin onboarding',
|
summary: 'Update admin onboarding',
|
||||||
description: 'Update the admin onboarding status.',
|
description: 'Update the admin onboarding status.',
|
||||||
|
history: new HistoryBuilder().added('v1').beta('v1').stable('v2'),
|
||||||
})
|
})
|
||||||
updateAdminOnboarding(@Body() dto: AdminOnboardingUpdateDto): Promise<void> {
|
updateAdminOnboarding(@Body() dto: AdminOnboardingUpdateDto): Promise<void> {
|
||||||
return this.service.updateAdminOnboarding(dto);
|
return this.service.updateAdminOnboarding(dto);
|
||||||
|
|
@ -37,9 +40,10 @@ export class SystemMetadataController {
|
||||||
|
|
||||||
@Get('reverse-geocoding-state')
|
@Get('reverse-geocoding-state')
|
||||||
@Authenticated({ permission: Permission.SystemMetadataRead, admin: true })
|
@Authenticated({ permission: Permission.SystemMetadataRead, admin: true })
|
||||||
@ApiOperation({
|
@Endpoint({
|
||||||
summary: 'Retrieve reverse geocoding state',
|
summary: 'Retrieve reverse geocoding state',
|
||||||
description: 'Retrieve the current state of the reverse geocoding import.',
|
description: 'Retrieve the current state of the reverse geocoding import.',
|
||||||
|
history: new HistoryBuilder().added('v1').beta('v1').stable('v2'),
|
||||||
})
|
})
|
||||||
getReverseGeocodingState(): Promise<ReverseGeocodingStateResponseDto> {
|
getReverseGeocodingState(): Promise<ReverseGeocodingStateResponseDto> {
|
||||||
return this.service.getReverseGeocodingState();
|
return this.service.getReverseGeocodingState();
|
||||||
|
|
@ -47,9 +51,10 @@ export class SystemMetadataController {
|
||||||
|
|
||||||
@Get('version-check-state')
|
@Get('version-check-state')
|
||||||
@Authenticated({ permission: Permission.SystemMetadataRead, admin: true })
|
@Authenticated({ permission: Permission.SystemMetadataRead, admin: true })
|
||||||
@ApiOperation({
|
@Endpoint({
|
||||||
summary: 'Retrieve version check state',
|
summary: 'Retrieve version check state',
|
||||||
description: 'Retrieve the current state of the version check process.',
|
description: 'Retrieve the current state of the version check process.',
|
||||||
|
history: new HistoryBuilder().added('v1').beta('v1').stable('v2'),
|
||||||
})
|
})
|
||||||
getVersionCheckState(): Promise<VersionCheckStateResponseDto> {
|
getVersionCheckState(): Promise<VersionCheckStateResponseDto> {
|
||||||
return this.service.getVersionCheckState();
|
return this.service.getVersionCheckState();
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,6 @@
|
||||||
import { Body, Controller, Delete, Get, HttpCode, HttpStatus, Param, Post, Put } from '@nestjs/common';
|
import { Body, Controller, Delete, Get, HttpCode, HttpStatus, Param, Post, Put } from '@nestjs/common';
|
||||||
import { ApiOperation, ApiTags } from '@nestjs/swagger';
|
import { ApiTags } from '@nestjs/swagger';
|
||||||
|
import { Endpoint, HistoryBuilder } from 'src/decorators';
|
||||||
import { BulkIdResponseDto, BulkIdsDto } from 'src/dtos/asset-ids.response.dto';
|
import { BulkIdResponseDto, BulkIdsDto } from 'src/dtos/asset-ids.response.dto';
|
||||||
import { AuthDto } from 'src/dtos/auth.dto';
|
import { AuthDto } from 'src/dtos/auth.dto';
|
||||||
import {
|
import {
|
||||||
|
|
@ -22,9 +23,10 @@ export class TagController {
|
||||||
|
|
||||||
@Post()
|
@Post()
|
||||||
@Authenticated({ permission: Permission.TagCreate })
|
@Authenticated({ permission: Permission.TagCreate })
|
||||||
@ApiOperation({
|
@Endpoint({
|
||||||
summary: 'Create a tag',
|
summary: 'Create a tag',
|
||||||
description: 'Create a new tag by providing a name and optional color.',
|
description: 'Create a new tag by providing a name and optional color.',
|
||||||
|
history: new HistoryBuilder().added('v1').beta('v1').stable('v2'),
|
||||||
})
|
})
|
||||||
createTag(@Auth() auth: AuthDto, @Body() dto: TagCreateDto): Promise<TagResponseDto> {
|
createTag(@Auth() auth: AuthDto, @Body() dto: TagCreateDto): Promise<TagResponseDto> {
|
||||||
return this.service.create(auth, dto);
|
return this.service.create(auth, dto);
|
||||||
|
|
@ -32,9 +34,10 @@ export class TagController {
|
||||||
|
|
||||||
@Get()
|
@Get()
|
||||||
@Authenticated({ permission: Permission.TagRead })
|
@Authenticated({ permission: Permission.TagRead })
|
||||||
@ApiOperation({
|
@Endpoint({
|
||||||
summary: 'Retrieve tags',
|
summary: 'Retrieve tags',
|
||||||
description: 'Retrieve a list of all tags.',
|
description: 'Retrieve a list of all tags.',
|
||||||
|
history: new HistoryBuilder().added('v1').beta('v1').stable('v2'),
|
||||||
})
|
})
|
||||||
getAllTags(@Auth() auth: AuthDto): Promise<TagResponseDto[]> {
|
getAllTags(@Auth() auth: AuthDto): Promise<TagResponseDto[]> {
|
||||||
return this.service.getAll(auth);
|
return this.service.getAll(auth);
|
||||||
|
|
@ -42,9 +45,10 @@ export class TagController {
|
||||||
|
|
||||||
@Put()
|
@Put()
|
||||||
@Authenticated({ permission: Permission.TagCreate })
|
@Authenticated({ permission: Permission.TagCreate })
|
||||||
@ApiOperation({
|
@Endpoint({
|
||||||
summary: 'Upsert tags',
|
summary: 'Upsert tags',
|
||||||
description: 'Create or update multiple tags in a single request.',
|
description: 'Create or update multiple tags in a single request.',
|
||||||
|
history: new HistoryBuilder().added('v1').beta('v1').stable('v2'),
|
||||||
})
|
})
|
||||||
upsertTags(@Auth() auth: AuthDto, @Body() dto: TagUpsertDto): Promise<TagResponseDto[]> {
|
upsertTags(@Auth() auth: AuthDto, @Body() dto: TagUpsertDto): Promise<TagResponseDto[]> {
|
||||||
return this.service.upsert(auth, dto);
|
return this.service.upsert(auth, dto);
|
||||||
|
|
@ -52,9 +56,10 @@ export class TagController {
|
||||||
|
|
||||||
@Put('assets')
|
@Put('assets')
|
||||||
@Authenticated({ permission: Permission.TagAsset })
|
@Authenticated({ permission: Permission.TagAsset })
|
||||||
@ApiOperation({
|
@Endpoint({
|
||||||
summary: 'Tag assets',
|
summary: 'Tag assets',
|
||||||
description: 'Add multiple tags to multiple assets in a single request.',
|
description: 'Add multiple tags to multiple assets in a single request.',
|
||||||
|
history: new HistoryBuilder().added('v1').beta('v1').stable('v2'),
|
||||||
})
|
})
|
||||||
bulkTagAssets(@Auth() auth: AuthDto, @Body() dto: TagBulkAssetsDto): Promise<TagBulkAssetsResponseDto> {
|
bulkTagAssets(@Auth() auth: AuthDto, @Body() dto: TagBulkAssetsDto): Promise<TagBulkAssetsResponseDto> {
|
||||||
return this.service.bulkTagAssets(auth, dto);
|
return this.service.bulkTagAssets(auth, dto);
|
||||||
|
|
@ -62,9 +67,10 @@ export class TagController {
|
||||||
|
|
||||||
@Get(':id')
|
@Get(':id')
|
||||||
@Authenticated({ permission: Permission.TagRead })
|
@Authenticated({ permission: Permission.TagRead })
|
||||||
@ApiOperation({
|
@Endpoint({
|
||||||
summary: 'Retrieve a tag',
|
summary: 'Retrieve a tag',
|
||||||
description: 'Retrieve a specific tag by its ID.',
|
description: 'Retrieve a specific tag by its ID.',
|
||||||
|
history: new HistoryBuilder().added('v1').beta('v1').stable('v2'),
|
||||||
})
|
})
|
||||||
getTagById(@Auth() auth: AuthDto, @Param() { id }: UUIDParamDto): Promise<TagResponseDto> {
|
getTagById(@Auth() auth: AuthDto, @Param() { id }: UUIDParamDto): Promise<TagResponseDto> {
|
||||||
return this.service.get(auth, id);
|
return this.service.get(auth, id);
|
||||||
|
|
@ -72,9 +78,10 @@ export class TagController {
|
||||||
|
|
||||||
@Put(':id')
|
@Put(':id')
|
||||||
@Authenticated({ permission: Permission.TagUpdate })
|
@Authenticated({ permission: Permission.TagUpdate })
|
||||||
@ApiOperation({
|
@Endpoint({
|
||||||
summary: 'Update a tag',
|
summary: 'Update a tag',
|
||||||
description: 'Update an existing tag identified by its ID.',
|
description: 'Update an existing tag identified by its ID.',
|
||||||
|
history: new HistoryBuilder().added('v1').beta('v1').stable('v2'),
|
||||||
})
|
})
|
||||||
updateTag(@Auth() auth: AuthDto, @Param() { id }: UUIDParamDto, @Body() dto: TagUpdateDto): Promise<TagResponseDto> {
|
updateTag(@Auth() auth: AuthDto, @Param() { id }: UUIDParamDto, @Body() dto: TagUpdateDto): Promise<TagResponseDto> {
|
||||||
return this.service.update(auth, id, dto);
|
return this.service.update(auth, id, dto);
|
||||||
|
|
@ -83,9 +90,10 @@ export class TagController {
|
||||||
@Delete(':id')
|
@Delete(':id')
|
||||||
@Authenticated({ permission: Permission.TagDelete })
|
@Authenticated({ permission: Permission.TagDelete })
|
||||||
@HttpCode(HttpStatus.NO_CONTENT)
|
@HttpCode(HttpStatus.NO_CONTENT)
|
||||||
@ApiOperation({
|
@Endpoint({
|
||||||
summary: 'Delete a tag',
|
summary: 'Delete a tag',
|
||||||
description: 'Delete a specific tag by its ID.',
|
description: 'Delete a specific tag by its ID.',
|
||||||
|
history: new HistoryBuilder().added('v1').beta('v1').stable('v2'),
|
||||||
})
|
})
|
||||||
deleteTag(@Auth() auth: AuthDto, @Param() { id }: UUIDParamDto): Promise<void> {
|
deleteTag(@Auth() auth: AuthDto, @Param() { id }: UUIDParamDto): Promise<void> {
|
||||||
return this.service.remove(auth, id);
|
return this.service.remove(auth, id);
|
||||||
|
|
@ -93,9 +101,10 @@ export class TagController {
|
||||||
|
|
||||||
@Put(':id/assets')
|
@Put(':id/assets')
|
||||||
@Authenticated({ permission: Permission.TagAsset })
|
@Authenticated({ permission: Permission.TagAsset })
|
||||||
@ApiOperation({
|
@Endpoint({
|
||||||
summary: 'Tag assets',
|
summary: 'Tag assets',
|
||||||
description: 'Add a tag to all the specified assets.',
|
description: 'Add a tag to all the specified assets.',
|
||||||
|
history: new HistoryBuilder().added('v1').beta('v1').stable('v2'),
|
||||||
})
|
})
|
||||||
tagAssets(
|
tagAssets(
|
||||||
@Auth() auth: AuthDto,
|
@Auth() auth: AuthDto,
|
||||||
|
|
@ -107,9 +116,10 @@ export class TagController {
|
||||||
|
|
||||||
@Delete(':id/assets')
|
@Delete(':id/assets')
|
||||||
@Authenticated({ permission: Permission.TagAsset })
|
@Authenticated({ permission: Permission.TagAsset })
|
||||||
@ApiOperation({
|
@Endpoint({
|
||||||
summary: 'Untag assets',
|
summary: 'Untag assets',
|
||||||
description: 'Remove a tag from all the specified assets.',
|
description: 'Remove a tag from all the specified assets.',
|
||||||
|
history: new HistoryBuilder().added('v1').beta('v1').stable('v2'),
|
||||||
})
|
})
|
||||||
untagAssets(
|
untagAssets(
|
||||||
@Auth() auth: AuthDto,
|
@Auth() auth: AuthDto,
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,6 @@
|
||||||
import { Controller, Get, Header, Query } from '@nestjs/common';
|
import { Controller, Get, Header, Query } from '@nestjs/common';
|
||||||
import { ApiOkResponse, ApiOperation, ApiTags } from '@nestjs/swagger';
|
import { ApiOkResponse, ApiTags } from '@nestjs/swagger';
|
||||||
|
import { Endpoint, HistoryBuilder } from 'src/decorators';
|
||||||
import { AuthDto } from 'src/dtos/auth.dto';
|
import { AuthDto } from 'src/dtos/auth.dto';
|
||||||
import { TimeBucketAssetDto, TimeBucketAssetResponseDto, TimeBucketDto } from 'src/dtos/time-bucket.dto';
|
import { TimeBucketAssetDto, TimeBucketAssetResponseDto, TimeBucketDto } from 'src/dtos/time-bucket.dto';
|
||||||
import { ApiTag, Permission } from 'src/enum';
|
import { ApiTag, Permission } from 'src/enum';
|
||||||
|
|
@ -13,7 +14,11 @@ export class TimelineController {
|
||||||
|
|
||||||
@Get('buckets')
|
@Get('buckets')
|
||||||
@Authenticated({ permission: Permission.AssetRead, sharedLink: true })
|
@Authenticated({ permission: Permission.AssetRead, sharedLink: true })
|
||||||
@ApiOperation({ summary: 'Get time buckets', description: 'Retrieve a list of all minimal time buckets.' })
|
@Endpoint({
|
||||||
|
summary: 'Get time buckets',
|
||||||
|
description: 'Retrieve a list of all minimal time buckets.',
|
||||||
|
history: new HistoryBuilder().added('v1').internal('v1'),
|
||||||
|
})
|
||||||
getTimeBuckets(@Auth() auth: AuthDto, @Query() dto: TimeBucketDto) {
|
getTimeBuckets(@Auth() auth: AuthDto, @Query() dto: TimeBucketDto) {
|
||||||
return this.service.getTimeBuckets(auth, dto);
|
return this.service.getTimeBuckets(auth, dto);
|
||||||
}
|
}
|
||||||
|
|
@ -22,9 +27,10 @@ export class TimelineController {
|
||||||
@Authenticated({ permission: Permission.AssetRead, sharedLink: true })
|
@Authenticated({ permission: Permission.AssetRead, sharedLink: true })
|
||||||
@ApiOkResponse({ type: TimeBucketAssetResponseDto })
|
@ApiOkResponse({ type: TimeBucketAssetResponseDto })
|
||||||
@Header('Content-Type', 'application/json')
|
@Header('Content-Type', 'application/json')
|
||||||
@ApiOperation({
|
@Endpoint({
|
||||||
summary: 'Get time bucket',
|
summary: 'Get time bucket',
|
||||||
description: 'Retrieve a string of all asset ids in a given time bucket.',
|
description: 'Retrieve a string of all asset ids in a given time bucket.',
|
||||||
|
history: new HistoryBuilder().added('v1').internal('v1'),
|
||||||
})
|
})
|
||||||
getTimeBucket(@Auth() auth: AuthDto, @Query() dto: TimeBucketAssetDto) {
|
getTimeBucket(@Auth() auth: AuthDto, @Query() dto: TimeBucketAssetDto) {
|
||||||
return this.service.getTimeBucket(auth, dto);
|
return this.service.getTimeBucket(auth, dto);
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,6 @@
|
||||||
import { Body, Controller, HttpCode, HttpStatus, Post } from '@nestjs/common';
|
import { Body, Controller, HttpCode, HttpStatus, Post } from '@nestjs/common';
|
||||||
import { ApiOperation, ApiTags } from '@nestjs/swagger';
|
import { ApiTags } from '@nestjs/swagger';
|
||||||
|
import { Endpoint, HistoryBuilder } from 'src/decorators';
|
||||||
import { BulkIdsDto } from 'src/dtos/asset-ids.response.dto';
|
import { BulkIdsDto } from 'src/dtos/asset-ids.response.dto';
|
||||||
import { AuthDto } from 'src/dtos/auth.dto';
|
import { AuthDto } from 'src/dtos/auth.dto';
|
||||||
import { TrashResponseDto } from 'src/dtos/trash.dto';
|
import { TrashResponseDto } from 'src/dtos/trash.dto';
|
||||||
|
|
@ -15,9 +16,10 @@ export class TrashController {
|
||||||
@Post('empty')
|
@Post('empty')
|
||||||
@Authenticated({ permission: Permission.AssetDelete })
|
@Authenticated({ permission: Permission.AssetDelete })
|
||||||
@HttpCode(HttpStatus.OK)
|
@HttpCode(HttpStatus.OK)
|
||||||
@ApiOperation({
|
@Endpoint({
|
||||||
summary: 'Empty trash',
|
summary: 'Empty trash',
|
||||||
description: 'Permanently delete all items in the trash.',
|
description: 'Permanently delete all items in the trash.',
|
||||||
|
history: new HistoryBuilder().added('v1').beta('v1').stable('v2'),
|
||||||
})
|
})
|
||||||
emptyTrash(@Auth() auth: AuthDto): Promise<TrashResponseDto> {
|
emptyTrash(@Auth() auth: AuthDto): Promise<TrashResponseDto> {
|
||||||
return this.service.empty(auth);
|
return this.service.empty(auth);
|
||||||
|
|
@ -26,9 +28,10 @@ export class TrashController {
|
||||||
@Post('restore')
|
@Post('restore')
|
||||||
@Authenticated({ permission: Permission.AssetDelete })
|
@Authenticated({ permission: Permission.AssetDelete })
|
||||||
@HttpCode(HttpStatus.OK)
|
@HttpCode(HttpStatus.OK)
|
||||||
@ApiOperation({
|
@Endpoint({
|
||||||
summary: 'Restore trash',
|
summary: 'Restore trash',
|
||||||
description: 'Restore all items in the trash.',
|
description: 'Restore all items in the trash.',
|
||||||
|
history: new HistoryBuilder().added('v1').beta('v1').stable('v2'),
|
||||||
})
|
})
|
||||||
restoreTrash(@Auth() auth: AuthDto): Promise<TrashResponseDto> {
|
restoreTrash(@Auth() auth: AuthDto): Promise<TrashResponseDto> {
|
||||||
return this.service.restore(auth);
|
return this.service.restore(auth);
|
||||||
|
|
@ -37,9 +40,10 @@ export class TrashController {
|
||||||
@Post('restore/assets')
|
@Post('restore/assets')
|
||||||
@Authenticated({ permission: Permission.AssetDelete })
|
@Authenticated({ permission: Permission.AssetDelete })
|
||||||
@HttpCode(HttpStatus.OK)
|
@HttpCode(HttpStatus.OK)
|
||||||
@ApiOperation({
|
@Endpoint({
|
||||||
summary: 'Restore assets',
|
summary: 'Restore assets',
|
||||||
description: 'Restore specific assets from the trash.',
|
description: 'Restore specific assets from the trash.',
|
||||||
|
history: new HistoryBuilder().added('v1').beta('v1').stable('v2'),
|
||||||
})
|
})
|
||||||
restoreAssets(@Auth() auth: AuthDto, @Body() dto: BulkIdsDto): Promise<TrashResponseDto> {
|
restoreAssets(@Auth() auth: AuthDto, @Body() dto: BulkIdsDto): Promise<TrashResponseDto> {
|
||||||
return this.service.restoreAssets(auth, dto);
|
return this.service.restoreAssets(auth, dto);
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,6 @@
|
||||||
import { Body, Controller, Delete, Get, HttpCode, HttpStatus, Param, Post, Put, Query } from '@nestjs/common';
|
import { Body, Controller, Delete, Get, HttpCode, HttpStatus, Param, Post, Put, Query } from '@nestjs/common';
|
||||||
import { ApiOperation, ApiTags } from '@nestjs/swagger';
|
import { ApiTags } from '@nestjs/swagger';
|
||||||
|
import { Endpoint, HistoryBuilder } from 'src/decorators';
|
||||||
import { AssetStatsDto, AssetStatsResponseDto } from 'src/dtos/asset.dto';
|
import { AssetStatsDto, AssetStatsResponseDto } from 'src/dtos/asset.dto';
|
||||||
import { AuthDto } from 'src/dtos/auth.dto';
|
import { AuthDto } from 'src/dtos/auth.dto';
|
||||||
import { SessionResponseDto } from 'src/dtos/session.dto';
|
import { SessionResponseDto } from 'src/dtos/session.dto';
|
||||||
|
|
@ -23,9 +24,10 @@ export class UserAdminController {
|
||||||
|
|
||||||
@Get()
|
@Get()
|
||||||
@Authenticated({ permission: Permission.AdminUserRead, admin: true })
|
@Authenticated({ permission: Permission.AdminUserRead, admin: true })
|
||||||
@ApiOperation({
|
@Endpoint({
|
||||||
summary: 'Search users',
|
summary: 'Search users',
|
||||||
description: 'Search for users.',
|
description: 'Search for users.',
|
||||||
|
history: new HistoryBuilder().added('v1').beta('v1').stable('v2'),
|
||||||
})
|
})
|
||||||
searchUsersAdmin(@Auth() auth: AuthDto, @Query() dto: UserAdminSearchDto): Promise<UserAdminResponseDto[]> {
|
searchUsersAdmin(@Auth() auth: AuthDto, @Query() dto: UserAdminSearchDto): Promise<UserAdminResponseDto[]> {
|
||||||
return this.service.search(auth, dto);
|
return this.service.search(auth, dto);
|
||||||
|
|
@ -33,9 +35,10 @@ export class UserAdminController {
|
||||||
|
|
||||||
@Post()
|
@Post()
|
||||||
@Authenticated({ permission: Permission.AdminUserCreate, admin: true })
|
@Authenticated({ permission: Permission.AdminUserCreate, admin: true })
|
||||||
@ApiOperation({
|
@Endpoint({
|
||||||
summary: 'Create a user',
|
summary: 'Create a user',
|
||||||
description: 'Create a new user.',
|
description: 'Create a new user.',
|
||||||
|
history: new HistoryBuilder().added('v1').beta('v1').stable('v2'),
|
||||||
})
|
})
|
||||||
createUserAdmin(@Body() createUserDto: UserAdminCreateDto): Promise<UserAdminResponseDto> {
|
createUserAdmin(@Body() createUserDto: UserAdminCreateDto): Promise<UserAdminResponseDto> {
|
||||||
return this.service.create(createUserDto);
|
return this.service.create(createUserDto);
|
||||||
|
|
@ -43,9 +46,10 @@ export class UserAdminController {
|
||||||
|
|
||||||
@Get(':id')
|
@Get(':id')
|
||||||
@Authenticated({ permission: Permission.AdminUserRead, admin: true })
|
@Authenticated({ permission: Permission.AdminUserRead, admin: true })
|
||||||
@ApiOperation({
|
@Endpoint({
|
||||||
summary: 'Retrieve a user',
|
summary: 'Retrieve a user',
|
||||||
description: 'Retrieve a specific user by their ID.',
|
description: 'Retrieve a specific user by their ID.',
|
||||||
|
history: new HistoryBuilder().added('v1').beta('v1').stable('v2'),
|
||||||
})
|
})
|
||||||
getUserAdmin(@Auth() auth: AuthDto, @Param() { id }: UUIDParamDto): Promise<UserAdminResponseDto> {
|
getUserAdmin(@Auth() auth: AuthDto, @Param() { id }: UUIDParamDto): Promise<UserAdminResponseDto> {
|
||||||
return this.service.get(auth, id);
|
return this.service.get(auth, id);
|
||||||
|
|
@ -53,9 +57,10 @@ export class UserAdminController {
|
||||||
|
|
||||||
@Put(':id')
|
@Put(':id')
|
||||||
@Authenticated({ permission: Permission.AdminUserUpdate, admin: true })
|
@Authenticated({ permission: Permission.AdminUserUpdate, admin: true })
|
||||||
@ApiOperation({
|
@Endpoint({
|
||||||
summary: 'Update a user',
|
summary: 'Update a user',
|
||||||
description: 'Update an existing user.',
|
description: 'Update an existing user.',
|
||||||
|
history: new HistoryBuilder().added('v1').beta('v1').stable('v2'),
|
||||||
})
|
})
|
||||||
updateUserAdmin(
|
updateUserAdmin(
|
||||||
@Auth() auth: AuthDto,
|
@Auth() auth: AuthDto,
|
||||||
|
|
@ -67,9 +72,10 @@ export class UserAdminController {
|
||||||
|
|
||||||
@Delete(':id')
|
@Delete(':id')
|
||||||
@Authenticated({ permission: Permission.AdminUserDelete, admin: true })
|
@Authenticated({ permission: Permission.AdminUserDelete, admin: true })
|
||||||
@ApiOperation({
|
@Endpoint({
|
||||||
summary: 'Delete a user',
|
summary: 'Delete a user',
|
||||||
description: 'Delete a user.',
|
description: 'Delete a user.',
|
||||||
|
history: new HistoryBuilder().added('v1').beta('v1').stable('v2'),
|
||||||
})
|
})
|
||||||
deleteUserAdmin(
|
deleteUserAdmin(
|
||||||
@Auth() auth: AuthDto,
|
@Auth() auth: AuthDto,
|
||||||
|
|
@ -81,9 +87,10 @@ export class UserAdminController {
|
||||||
|
|
||||||
@Get(':id/sessions')
|
@Get(':id/sessions')
|
||||||
@Authenticated({ permission: Permission.AdminSessionRead, admin: true })
|
@Authenticated({ permission: Permission.AdminSessionRead, admin: true })
|
||||||
@ApiOperation({
|
@Endpoint({
|
||||||
summary: 'Retrieve user sessions',
|
summary: 'Retrieve user sessions',
|
||||||
description: 'Retrieve all sessions for a specific user.',
|
description: 'Retrieve all sessions for a specific user.',
|
||||||
|
history: new HistoryBuilder().added('v1').beta('v1').stable('v2'),
|
||||||
})
|
})
|
||||||
getUserSessionsAdmin(@Auth() auth: AuthDto, @Param() { id }: UUIDParamDto): Promise<SessionResponseDto[]> {
|
getUserSessionsAdmin(@Auth() auth: AuthDto, @Param() { id }: UUIDParamDto): Promise<SessionResponseDto[]> {
|
||||||
return this.service.getSessions(auth, id);
|
return this.service.getSessions(auth, id);
|
||||||
|
|
@ -91,9 +98,10 @@ export class UserAdminController {
|
||||||
|
|
||||||
@Get(':id/statistics')
|
@Get(':id/statistics')
|
||||||
@Authenticated({ permission: Permission.AdminUserRead, admin: true })
|
@Authenticated({ permission: Permission.AdminUserRead, admin: true })
|
||||||
@ApiOperation({
|
@Endpoint({
|
||||||
summary: 'Retrieve user statistics',
|
summary: 'Retrieve user statistics',
|
||||||
description: 'Retrieve asset statistics for a specific user.',
|
description: 'Retrieve asset statistics for a specific user.',
|
||||||
|
history: new HistoryBuilder().added('v1').beta('v1').stable('v2'),
|
||||||
})
|
})
|
||||||
getUserStatisticsAdmin(
|
getUserStatisticsAdmin(
|
||||||
@Auth() auth: AuthDto,
|
@Auth() auth: AuthDto,
|
||||||
|
|
@ -105,9 +113,10 @@ export class UserAdminController {
|
||||||
|
|
||||||
@Get(':id/preferences')
|
@Get(':id/preferences')
|
||||||
@Authenticated({ permission: Permission.AdminUserRead, admin: true })
|
@Authenticated({ permission: Permission.AdminUserRead, admin: true })
|
||||||
@ApiOperation({
|
@Endpoint({
|
||||||
summary: 'Retrieve user preferences',
|
summary: 'Retrieve user preferences',
|
||||||
description: 'Retrieve the preferences of a specific user.',
|
description: 'Retrieve the preferences of a specific user.',
|
||||||
|
history: new HistoryBuilder().added('v1').beta('v1').stable('v2'),
|
||||||
})
|
})
|
||||||
getUserPreferencesAdmin(@Auth() auth: AuthDto, @Param() { id }: UUIDParamDto): Promise<UserPreferencesResponseDto> {
|
getUserPreferencesAdmin(@Auth() auth: AuthDto, @Param() { id }: UUIDParamDto): Promise<UserPreferencesResponseDto> {
|
||||||
return this.service.getPreferences(auth, id);
|
return this.service.getPreferences(auth, id);
|
||||||
|
|
@ -115,9 +124,10 @@ export class UserAdminController {
|
||||||
|
|
||||||
@Put(':id/preferences')
|
@Put(':id/preferences')
|
||||||
@Authenticated({ permission: Permission.AdminUserUpdate, admin: true })
|
@Authenticated({ permission: Permission.AdminUserUpdate, admin: true })
|
||||||
@ApiOperation({
|
@Endpoint({
|
||||||
summary: 'Update user preferences',
|
summary: 'Update user preferences',
|
||||||
description: 'Update the preferences of a specific user.',
|
description: 'Update the preferences of a specific user.',
|
||||||
|
history: new HistoryBuilder().added('v1').beta('v1').stable('v2'),
|
||||||
})
|
})
|
||||||
updateUserPreferencesAdmin(
|
updateUserPreferencesAdmin(
|
||||||
@Auth() auth: AuthDto,
|
@Auth() auth: AuthDto,
|
||||||
|
|
@ -130,9 +140,10 @@ export class UserAdminController {
|
||||||
@Post(':id/restore')
|
@Post(':id/restore')
|
||||||
@Authenticated({ permission: Permission.AdminUserDelete, admin: true })
|
@Authenticated({ permission: Permission.AdminUserDelete, admin: true })
|
||||||
@HttpCode(HttpStatus.OK)
|
@HttpCode(HttpStatus.OK)
|
||||||
@ApiOperation({
|
@Endpoint({
|
||||||
summary: 'Restore a deleted user',
|
summary: 'Restore a deleted user',
|
||||||
description: 'Restore a previously deleted user.',
|
description: 'Restore a previously deleted user.',
|
||||||
|
history: new HistoryBuilder().added('v1').beta('v1').stable('v2'),
|
||||||
})
|
})
|
||||||
restoreUserAdmin(@Auth() auth: AuthDto, @Param() { id }: UUIDParamDto): Promise<UserAdminResponseDto> {
|
restoreUserAdmin(@Auth() auth: AuthDto, @Param() { id }: UUIDParamDto): Promise<UserAdminResponseDto> {
|
||||||
return this.service.restore(auth, id);
|
return this.service.restore(auth, id);
|
||||||
|
|
|
||||||
|
|
@ -13,8 +13,9 @@ import {
|
||||||
UploadedFile,
|
UploadedFile,
|
||||||
UseInterceptors,
|
UseInterceptors,
|
||||||
} from '@nestjs/common';
|
} from '@nestjs/common';
|
||||||
import { ApiBody, ApiConsumes, ApiOperation, ApiTags } from '@nestjs/swagger';
|
import { ApiBody, ApiConsumes, ApiTags } from '@nestjs/swagger';
|
||||||
import { NextFunction, Response } from 'express';
|
import { NextFunction, Response } from 'express';
|
||||||
|
import { Endpoint, HistoryBuilder } from 'src/decorators';
|
||||||
import { AuthDto } from 'src/dtos/auth.dto';
|
import { AuthDto } from 'src/dtos/auth.dto';
|
||||||
import { LicenseKeyDto, LicenseResponseDto } from 'src/dtos/license.dto';
|
import { LicenseKeyDto, LicenseResponseDto } from 'src/dtos/license.dto';
|
||||||
import { OnboardingDto, OnboardingResponseDto } from 'src/dtos/onboarding.dto';
|
import { OnboardingDto, OnboardingResponseDto } from 'src/dtos/onboarding.dto';
|
||||||
|
|
@ -39,16 +40,21 @@ export class UserController {
|
||||||
|
|
||||||
@Get()
|
@Get()
|
||||||
@Authenticated({ permission: Permission.UserRead })
|
@Authenticated({ permission: Permission.UserRead })
|
||||||
@ApiOperation({ summary: 'Get all users', description: 'Retrieve a list of all users on the server.' })
|
@Endpoint({
|
||||||
|
summary: 'Get all users',
|
||||||
|
description: 'Retrieve a list of all users on the server.',
|
||||||
|
history: new HistoryBuilder().added('v1').beta('v1').stable('v2'),
|
||||||
|
})
|
||||||
searchUsers(@Auth() auth: AuthDto): Promise<UserResponseDto[]> {
|
searchUsers(@Auth() auth: AuthDto): Promise<UserResponseDto[]> {
|
||||||
return this.service.search(auth);
|
return this.service.search(auth);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Get('me')
|
@Get('me')
|
||||||
@Authenticated({ permission: Permission.UserRead })
|
@Authenticated({ permission: Permission.UserRead })
|
||||||
@ApiOperation({
|
@Endpoint({
|
||||||
summary: 'Get current user',
|
summary: 'Get current user',
|
||||||
description: 'Retrieve information about the user making the API request.',
|
description: 'Retrieve information about the user making the API request.',
|
||||||
|
history: new HistoryBuilder().added('v1').beta('v1').stable('v2'),
|
||||||
})
|
})
|
||||||
getMyUser(@Auth() auth: AuthDto): Promise<UserAdminResponseDto> {
|
getMyUser(@Auth() auth: AuthDto): Promise<UserAdminResponseDto> {
|
||||||
return this.service.getMe(auth);
|
return this.service.getMe(auth);
|
||||||
|
|
@ -56,21 +62,33 @@ export class UserController {
|
||||||
|
|
||||||
@Put('me')
|
@Put('me')
|
||||||
@Authenticated({ permission: Permission.UserUpdate })
|
@Authenticated({ permission: Permission.UserUpdate })
|
||||||
@ApiOperation({ summary: 'Update current user', description: 'Update the current user making teh API request.' })
|
@Endpoint({
|
||||||
|
summary: 'Update current user',
|
||||||
|
description: 'Update the current user making teh API request.',
|
||||||
|
history: new HistoryBuilder().added('v1').beta('v1').stable('v2'),
|
||||||
|
})
|
||||||
updateMyUser(@Auth() auth: AuthDto, @Body() dto: UserUpdateMeDto): Promise<UserAdminResponseDto> {
|
updateMyUser(@Auth() auth: AuthDto, @Body() dto: UserUpdateMeDto): Promise<UserAdminResponseDto> {
|
||||||
return this.service.updateMe(auth, dto);
|
return this.service.updateMe(auth, dto);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Get('me/preferences')
|
@Get('me/preferences')
|
||||||
@Authenticated({ permission: Permission.UserPreferenceRead })
|
@Authenticated({ permission: Permission.UserPreferenceRead })
|
||||||
@ApiOperation({ summary: 'Get my preferences', description: 'Retrieve the preferences for the current user.' })
|
@Endpoint({
|
||||||
|
summary: 'Get my preferences',
|
||||||
|
description: 'Retrieve the preferences for the current user.',
|
||||||
|
history: new HistoryBuilder().added('v1').beta('v1').stable('v2'),
|
||||||
|
})
|
||||||
getMyPreferences(@Auth() auth: AuthDto): Promise<UserPreferencesResponseDto> {
|
getMyPreferences(@Auth() auth: AuthDto): Promise<UserPreferencesResponseDto> {
|
||||||
return this.service.getMyPreferences(auth);
|
return this.service.getMyPreferences(auth);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Put('me/preferences')
|
@Put('me/preferences')
|
||||||
@Authenticated({ permission: Permission.UserPreferenceUpdate })
|
@Authenticated({ permission: Permission.UserPreferenceUpdate })
|
||||||
@ApiOperation({ summary: 'Update my preferences', description: 'Update the preferences of the current user.' })
|
@Endpoint({
|
||||||
|
summary: 'Update my preferences',
|
||||||
|
description: 'Update the preferences of the current user.',
|
||||||
|
history: new HistoryBuilder().added('v1').beta('v1').stable('v2'),
|
||||||
|
})
|
||||||
updateMyPreferences(
|
updateMyPreferences(
|
||||||
@Auth() auth: AuthDto,
|
@Auth() auth: AuthDto,
|
||||||
@Body() dto: UserPreferencesUpdateDto,
|
@Body() dto: UserPreferencesUpdateDto,
|
||||||
|
|
@ -80,9 +98,10 @@ export class UserController {
|
||||||
|
|
||||||
@Get('me/license')
|
@Get('me/license')
|
||||||
@Authenticated({ permission: Permission.UserLicenseRead })
|
@Authenticated({ permission: Permission.UserLicenseRead })
|
||||||
@ApiOperation({
|
@Endpoint({
|
||||||
summary: 'Retrieve user product key',
|
summary: 'Retrieve user product key',
|
||||||
description: 'Retrieve information about whether the current user has a registered product key.',
|
description: 'Retrieve information about whether the current user has a registered product key.',
|
||||||
|
history: new HistoryBuilder().added('v1').beta('v1').stable('v2'),
|
||||||
})
|
})
|
||||||
getUserLicense(@Auth() auth: AuthDto): Promise<LicenseResponseDto> {
|
getUserLicense(@Auth() auth: AuthDto): Promise<LicenseResponseDto> {
|
||||||
return this.service.getLicense(auth);
|
return this.service.getLicense(auth);
|
||||||
|
|
@ -90,9 +109,10 @@ export class UserController {
|
||||||
|
|
||||||
@Put('me/license')
|
@Put('me/license')
|
||||||
@Authenticated({ permission: Permission.UserLicenseUpdate })
|
@Authenticated({ permission: Permission.UserLicenseUpdate })
|
||||||
@ApiOperation({
|
@Endpoint({
|
||||||
summary: 'Set user product key',
|
summary: 'Set user product key',
|
||||||
description: 'Register a product key for the current user.',
|
description: 'Register a product key for the current user.',
|
||||||
|
history: new HistoryBuilder().added('v1').beta('v1').stable('v2'),
|
||||||
})
|
})
|
||||||
async setUserLicense(@Auth() auth: AuthDto, @Body() license: LicenseKeyDto): Promise<LicenseResponseDto> {
|
async setUserLicense(@Auth() auth: AuthDto, @Body() license: LicenseKeyDto): Promise<LicenseResponseDto> {
|
||||||
return this.service.setLicense(auth, license);
|
return this.service.setLicense(auth, license);
|
||||||
|
|
@ -101,9 +121,10 @@ export class UserController {
|
||||||
@Delete('me/license')
|
@Delete('me/license')
|
||||||
@Authenticated({ permission: Permission.UserLicenseDelete })
|
@Authenticated({ permission: Permission.UserLicenseDelete })
|
||||||
@HttpCode(HttpStatus.NO_CONTENT)
|
@HttpCode(HttpStatus.NO_CONTENT)
|
||||||
@ApiOperation({
|
@Endpoint({
|
||||||
summary: 'Delete user product key',
|
summary: 'Delete user product key',
|
||||||
description: 'Delete the registered product key for the current user.',
|
description: 'Delete the registered product key for the current user.',
|
||||||
|
history: new HistoryBuilder().added('v1').beta('v1').stable('v2'),
|
||||||
})
|
})
|
||||||
async deleteUserLicense(@Auth() auth: AuthDto): Promise<void> {
|
async deleteUserLicense(@Auth() auth: AuthDto): Promise<void> {
|
||||||
await this.service.deleteLicense(auth);
|
await this.service.deleteLicense(auth);
|
||||||
|
|
@ -111,9 +132,10 @@ export class UserController {
|
||||||
|
|
||||||
@Get('me/onboarding')
|
@Get('me/onboarding')
|
||||||
@Authenticated({ permission: Permission.UserOnboardingRead })
|
@Authenticated({ permission: Permission.UserOnboardingRead })
|
||||||
@ApiOperation({
|
@Endpoint({
|
||||||
summary: 'Retrieve user onboarding',
|
summary: 'Retrieve user onboarding',
|
||||||
description: 'Retrieve the onboarding status of the current user.',
|
description: 'Retrieve the onboarding status of the current user.',
|
||||||
|
history: new HistoryBuilder().added('v1').beta('v1').stable('v2'),
|
||||||
})
|
})
|
||||||
getUserOnboarding(@Auth() auth: AuthDto): Promise<OnboardingResponseDto> {
|
getUserOnboarding(@Auth() auth: AuthDto): Promise<OnboardingResponseDto> {
|
||||||
return this.service.getOnboarding(auth);
|
return this.service.getOnboarding(auth);
|
||||||
|
|
@ -121,9 +143,10 @@ export class UserController {
|
||||||
|
|
||||||
@Put('me/onboarding')
|
@Put('me/onboarding')
|
||||||
@Authenticated({ permission: Permission.UserOnboardingUpdate })
|
@Authenticated({ permission: Permission.UserOnboardingUpdate })
|
||||||
@ApiOperation({
|
@Endpoint({
|
||||||
summary: 'Update user onboarding',
|
summary: 'Update user onboarding',
|
||||||
description: 'Update the onboarding status of the current user.',
|
description: 'Update the onboarding status of the current user.',
|
||||||
|
history: new HistoryBuilder().added('v1').beta('v1').stable('v2'),
|
||||||
})
|
})
|
||||||
async setUserOnboarding(@Auth() auth: AuthDto, @Body() Onboarding: OnboardingDto): Promise<OnboardingResponseDto> {
|
async setUserOnboarding(@Auth() auth: AuthDto, @Body() Onboarding: OnboardingDto): Promise<OnboardingResponseDto> {
|
||||||
return this.service.setOnboarding(auth, Onboarding);
|
return this.service.setOnboarding(auth, Onboarding);
|
||||||
|
|
@ -132,9 +155,10 @@ export class UserController {
|
||||||
@Delete('me/onboarding')
|
@Delete('me/onboarding')
|
||||||
@Authenticated({ permission: Permission.UserOnboardingDelete })
|
@Authenticated({ permission: Permission.UserOnboardingDelete })
|
||||||
@HttpCode(HttpStatus.NO_CONTENT)
|
@HttpCode(HttpStatus.NO_CONTENT)
|
||||||
@ApiOperation({
|
@Endpoint({
|
||||||
summary: 'Delete user onboarding',
|
summary: 'Delete user onboarding',
|
||||||
description: 'Delete the onboarding status of the current user.',
|
description: 'Delete the onboarding status of the current user.',
|
||||||
|
history: new HistoryBuilder().added('v1').beta('v1').stable('v2'),
|
||||||
})
|
})
|
||||||
async deleteUserOnboarding(@Auth() auth: AuthDto): Promise<void> {
|
async deleteUserOnboarding(@Auth() auth: AuthDto): Promise<void> {
|
||||||
await this.service.deleteOnboarding(auth);
|
await this.service.deleteOnboarding(auth);
|
||||||
|
|
@ -142,9 +166,10 @@ export class UserController {
|
||||||
|
|
||||||
@Get(':id')
|
@Get(':id')
|
||||||
@Authenticated({ permission: Permission.UserRead })
|
@Authenticated({ permission: Permission.UserRead })
|
||||||
@ApiOperation({
|
@Endpoint({
|
||||||
summary: 'Retrieve a user',
|
summary: 'Retrieve a user',
|
||||||
description: 'Retrieve a specific user by their ID.',
|
description: 'Retrieve a specific user by their ID.',
|
||||||
|
history: new HistoryBuilder().added('v1').beta('v1').stable('v2'),
|
||||||
})
|
})
|
||||||
getUser(@Param() { id }: UUIDParamDto): Promise<UserResponseDto> {
|
getUser(@Param() { id }: UUIDParamDto): Promise<UserResponseDto> {
|
||||||
return this.service.get(id);
|
return this.service.get(id);
|
||||||
|
|
@ -155,9 +180,10 @@ export class UserController {
|
||||||
@UseInterceptors(FileUploadInterceptor)
|
@UseInterceptors(FileUploadInterceptor)
|
||||||
@ApiConsumes('multipart/form-data')
|
@ApiConsumes('multipart/form-data')
|
||||||
@ApiBody({ description: 'A new avatar for the user', type: CreateProfileImageDto })
|
@ApiBody({ description: 'A new avatar for the user', type: CreateProfileImageDto })
|
||||||
@ApiOperation({
|
@Endpoint({
|
||||||
summary: 'Create user profile image',
|
summary: 'Create user profile image',
|
||||||
description: 'Upload and set a new profile image for the current user.',
|
description: 'Upload and set a new profile image for the current user.',
|
||||||
|
history: new HistoryBuilder().added('v1').beta('v1').stable('v2'),
|
||||||
})
|
})
|
||||||
createProfileImage(
|
createProfileImage(
|
||||||
@Auth() auth: AuthDto,
|
@Auth() auth: AuthDto,
|
||||||
|
|
@ -169,9 +195,10 @@ export class UserController {
|
||||||
@Delete('profile-image')
|
@Delete('profile-image')
|
||||||
@Authenticated({ permission: Permission.UserProfileImageDelete })
|
@Authenticated({ permission: Permission.UserProfileImageDelete })
|
||||||
@HttpCode(HttpStatus.NO_CONTENT)
|
@HttpCode(HttpStatus.NO_CONTENT)
|
||||||
@ApiOperation({
|
@Endpoint({
|
||||||
summary: 'Delete user profile image',
|
summary: 'Delete user profile image',
|
||||||
description: 'Delete the profile image of the current user.',
|
description: 'Delete the profile image of the current user.',
|
||||||
|
history: new HistoryBuilder().added('v1').beta('v1').stable('v2'),
|
||||||
})
|
})
|
||||||
deleteProfileImage(@Auth() auth: AuthDto): Promise<void> {
|
deleteProfileImage(@Auth() auth: AuthDto): Promise<void> {
|
||||||
return this.service.deleteProfileImage(auth);
|
return this.service.deleteProfileImage(auth);
|
||||||
|
|
@ -180,9 +207,10 @@ export class UserController {
|
||||||
@Get(':id/profile-image')
|
@Get(':id/profile-image')
|
||||||
@FileResponse()
|
@FileResponse()
|
||||||
@Authenticated({ permission: Permission.UserProfileImageRead })
|
@Authenticated({ permission: Permission.UserProfileImageRead })
|
||||||
@ApiOperation({
|
@Endpoint({
|
||||||
summary: 'Retrieve user profile image',
|
summary: 'Retrieve user profile image',
|
||||||
description: 'Retrieve the profile image file for a user.',
|
description: 'Retrieve the profile image file for a user.',
|
||||||
|
history: new HistoryBuilder().added('v1').beta('v1').stable('v2'),
|
||||||
})
|
})
|
||||||
async getProfileImage(@Res() res: Response, @Next() next: NextFunction, @Param() { id }: UUIDParamDto) {
|
async getProfileImage(@Res() res: Response, @Next() next: NextFunction, @Param() { id }: UUIDParamDto) {
|
||||||
await sendFile(res, next, () => this.service.getProfileImage(id), this.logger);
|
await sendFile(res, next, () => this.service.getProfileImage(id), this.logger);
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,6 @@
|
||||||
import { Controller, Get, Query } from '@nestjs/common';
|
import { Controller, Get, Query } from '@nestjs/common';
|
||||||
import { ApiOperation, ApiTags } from '@nestjs/swagger';
|
import { ApiTags } from '@nestjs/swagger';
|
||||||
|
import { Endpoint, HistoryBuilder } from 'src/decorators';
|
||||||
import { AssetResponseDto } from 'src/dtos/asset-response.dto';
|
import { AssetResponseDto } from 'src/dtos/asset-response.dto';
|
||||||
import { AuthDto } from 'src/dtos/auth.dto';
|
import { AuthDto } from 'src/dtos/auth.dto';
|
||||||
import { ApiTag } from 'src/enum';
|
import { ApiTag } from 'src/enum';
|
||||||
|
|
@ -13,9 +14,10 @@ export class ViewController {
|
||||||
|
|
||||||
@Get('folder/unique-paths')
|
@Get('folder/unique-paths')
|
||||||
@Authenticated()
|
@Authenticated()
|
||||||
@ApiOperation({
|
@Endpoint({
|
||||||
summary: 'Retrieve unique paths',
|
summary: 'Retrieve unique paths',
|
||||||
description: 'Retrieve a list of unique folder paths from asset original paths.',
|
description: 'Retrieve a list of unique folder paths from asset original paths.',
|
||||||
|
history: new HistoryBuilder().added('v1').beta('v1').stable('v2'),
|
||||||
})
|
})
|
||||||
getUniqueOriginalPaths(@Auth() auth: AuthDto): Promise<string[]> {
|
getUniqueOriginalPaths(@Auth() auth: AuthDto): Promise<string[]> {
|
||||||
return this.service.getUniqueOriginalPaths(auth);
|
return this.service.getUniqueOriginalPaths(auth);
|
||||||
|
|
@ -23,9 +25,10 @@ export class ViewController {
|
||||||
|
|
||||||
@Get('folder')
|
@Get('folder')
|
||||||
@Authenticated()
|
@Authenticated()
|
||||||
@ApiOperation({
|
@Endpoint({
|
||||||
summary: 'Retrieve assets by original path',
|
summary: 'Retrieve assets by original path',
|
||||||
description: 'Retrieve assets that are children of a specific folder.',
|
description: 'Retrieve assets that are children of a specific folder.',
|
||||||
|
history: new HistoryBuilder().added('v1').beta('v1').stable('v2'),
|
||||||
})
|
})
|
||||||
getAssetsByOriginalPath(@Auth() auth: AuthDto, @Query('path') path: string): Promise<AssetResponseDto[]> {
|
getAssetsByOriginalPath(@Auth() auth: AuthDto, @Query('path') path: string): Promise<AssetResponseDto[]> {
|
||||||
return this.service.getAssetsByOriginalPath(auth, path);
|
return this.service.getAssetsByOriginalPath(auth, path);
|
||||||
|
|
|
||||||
|
|
@ -2,8 +2,6 @@ import { StorageCore } from 'src/cores/storage.core';
|
||||||
import { vitest } from 'vitest';
|
import { vitest } from 'vitest';
|
||||||
|
|
||||||
vitest.mock('src/constants', () => ({
|
vitest.mock('src/constants', () => ({
|
||||||
ADDED_IN_PREFIX: 'This property was added in ',
|
|
||||||
DEPRECATED_IN_PREFIX: 'This property was deprecated in ',
|
|
||||||
IWorker: 'IWorker',
|
IWorker: 'IWorker',
|
||||||
}));
|
}));
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,7 @@
|
||||||
import { SetMetadata, applyDecorators } from '@nestjs/common';
|
import { SetMetadata, applyDecorators } from '@nestjs/common';
|
||||||
import { ApiExtension, ApiOperation, ApiOperationOptions, ApiProperty, ApiTags } from '@nestjs/swagger';
|
import { ApiOperation, ApiOperationOptions, ApiProperty, ApiPropertyOptions, ApiTags } from '@nestjs/swagger';
|
||||||
import _ from 'lodash';
|
import _ from 'lodash';
|
||||||
import { ADDED_IN_PREFIX, DEPRECATED_IN_PREFIX, LIFECYCLE_EXTENSION } from 'src/constants';
|
import { ApiCustomExtension, ApiTag, ImmichWorker, JobName, MetadataKey, QueueName } from 'src/enum';
|
||||||
import { ApiTag, ImmichWorker, JobName, MetadataKey, QueueName } from 'src/enum';
|
|
||||||
import { EmitEvent } from 'src/repositories/event.repository';
|
import { EmitEvent } from 'src/repositories/event.repository';
|
||||||
import { immich_uuid_v7, updated_at } from 'src/schema/functions';
|
import { immich_uuid_v7, updated_at } from 'src/schema/functions';
|
||||||
import { BeforeUpdateTrigger, Column, ColumnOptions } from 'src/sql-tools';
|
import { BeforeUpdateTrigger, Column, ColumnOptions } from 'src/sql-tools';
|
||||||
|
|
@ -153,39 +152,122 @@ export type JobConfig = {
|
||||||
};
|
};
|
||||||
export const OnJob = (config: JobConfig) => SetMetadata(MetadataKey.JobConfig, config);
|
export const OnJob = (config: JobConfig) => SetMetadata(MetadataKey.JobConfig, config);
|
||||||
|
|
||||||
type LifecycleRelease = 'NEXT_RELEASE' | string;
|
type EndpointOptions = ApiOperationOptions & { history?: HistoryBuilder };
|
||||||
type LifecycleMetadata = {
|
export const Endpoint = ({ history, ...options }: EndpointOptions) => {
|
||||||
addedAt?: LifecycleRelease;
|
const decorators: MethodDecorator[] = [];
|
||||||
deprecatedAt?: LifecycleRelease;
|
const extensions = history?.getExtensions() ?? {};
|
||||||
};
|
|
||||||
|
|
||||||
export const EndpointLifecycle = ({
|
if (!extensions[ApiCustomExtension.History]) {
|
||||||
addedAt,
|
console.log(`Missing history for endpoint: ${options.summary}`);
|
||||||
deprecatedAt,
|
|
||||||
description,
|
|
||||||
...options
|
|
||||||
}: LifecycleMetadata & ApiOperationOptions) => {
|
|
||||||
const decorators: MethodDecorator[] = [ApiExtension(LIFECYCLE_EXTENSION, { addedAt, deprecatedAt })];
|
|
||||||
if (deprecatedAt) {
|
|
||||||
decorators.push(
|
|
||||||
ApiTags(ApiTag.Deprecated),
|
|
||||||
ApiOperation({
|
|
||||||
deprecated: true,
|
|
||||||
description: DEPRECATED_IN_PREFIX + deprecatedAt + (description ? `. ${description}` : ''),
|
|
||||||
...options,
|
|
||||||
}),
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (history?.isDeprecated()) {
|
||||||
|
options.deprecated = true;
|
||||||
|
decorators.push(ApiTags(ApiTag.Deprecated));
|
||||||
|
}
|
||||||
|
|
||||||
|
decorators.push(ApiOperation({ ...options, ...extensions }));
|
||||||
|
|
||||||
return applyDecorators(...decorators);
|
return applyDecorators(...decorators);
|
||||||
};
|
};
|
||||||
|
|
||||||
export const PropertyLifecycle = ({ addedAt, deprecatedAt }: LifecycleMetadata) => {
|
type PropertyOptions = ApiPropertyOptions & { history?: HistoryBuilder };
|
||||||
const decorators: PropertyDecorator[] = [];
|
export const Property = ({ history, ...options }: PropertyOptions) => {
|
||||||
decorators.push(ApiProperty({ description: ADDED_IN_PREFIX + addedAt }));
|
const extensions = history?.getExtensions() ?? {};
|
||||||
if (deprecatedAt) {
|
|
||||||
decorators.push(ApiProperty({ deprecated: true, description: DEPRECATED_IN_PREFIX + deprecatedAt }));
|
if (history?.isDeprecated()) {
|
||||||
|
options.deprecated = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
return applyDecorators(...decorators);
|
return ApiProperty({ ...options, ...extensions });
|
||||||
};
|
};
|
||||||
|
|
||||||
|
type HistoryEntry = {
|
||||||
|
version: string;
|
||||||
|
state: ApiState | 'Added' | 'Updated';
|
||||||
|
description?: string;
|
||||||
|
replacementId?: string;
|
||||||
|
};
|
||||||
|
|
||||||
|
type DeprecatedOptions = {
|
||||||
|
/** replacement operationId */
|
||||||
|
replacementId?: string;
|
||||||
|
};
|
||||||
|
|
||||||
|
type CustomExtensions = {
|
||||||
|
[ApiCustomExtension.State]?: ApiState;
|
||||||
|
[ApiCustomExtension.History]?: HistoryEntry[];
|
||||||
|
};
|
||||||
|
|
||||||
|
enum ApiState {
|
||||||
|
'Stable' = 'Stable',
|
||||||
|
'Alpha' = 'Alpha',
|
||||||
|
'Beta' = 'Beta',
|
||||||
|
'Internal' = 'Internal',
|
||||||
|
'Deprecated' = 'Deprecated',
|
||||||
|
}
|
||||||
|
export class HistoryBuilder {
|
||||||
|
private hasDeprecated = false;
|
||||||
|
private items: HistoryEntry[] = [];
|
||||||
|
|
||||||
|
added(version: string, description?: string) {
|
||||||
|
return this.push({ version, state: 'Added', description });
|
||||||
|
}
|
||||||
|
|
||||||
|
updated(version: string, description: string) {
|
||||||
|
return this.push({ version, state: 'Updated', description });
|
||||||
|
}
|
||||||
|
|
||||||
|
alpha(version: string) {
|
||||||
|
return this.push({ version, state: ApiState.Alpha });
|
||||||
|
}
|
||||||
|
|
||||||
|
beta(version: string) {
|
||||||
|
return this.push({ version, state: ApiState.Beta });
|
||||||
|
}
|
||||||
|
|
||||||
|
internal(version: string) {
|
||||||
|
return this.push({ version, state: ApiState.Internal });
|
||||||
|
}
|
||||||
|
|
||||||
|
stable(version: string) {
|
||||||
|
return this.push({ version, state: ApiState.Stable });
|
||||||
|
}
|
||||||
|
|
||||||
|
deprecated(version: string, options?: DeprecatedOptions) {
|
||||||
|
const { replacementId } = options || {};
|
||||||
|
this.hasDeprecated = true;
|
||||||
|
return this.push({ version, state: ApiState.Deprecated, replacementId });
|
||||||
|
}
|
||||||
|
|
||||||
|
isDeprecated(): boolean {
|
||||||
|
return this.hasDeprecated;
|
||||||
|
}
|
||||||
|
|
||||||
|
getExtensions() {
|
||||||
|
const extensions: CustomExtensions = {};
|
||||||
|
|
||||||
|
if (this.items.length > 0) {
|
||||||
|
extensions[ApiCustomExtension.History] = this.items;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (const item of this.items.toReversed()) {
|
||||||
|
if (item.state === 'Added' || item.state === 'Updated') {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
extensions[ApiCustomExtension.State] = item.state;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return extensions;
|
||||||
|
}
|
||||||
|
|
||||||
|
private push(item: HistoryEntry) {
|
||||||
|
if (!item.version.startsWith('v')) {
|
||||||
|
throw new Error(`Version string must start with 'v': received '${JSON.stringify(item)}'`);
|
||||||
|
}
|
||||||
|
this.items.push(item);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
import { ApiProperty } from '@nestjs/swagger';
|
import { ApiProperty } from '@nestjs/swagger';
|
||||||
import { Selectable } from 'kysely';
|
import { Selectable } from 'kysely';
|
||||||
import { AssetFace, AssetFile, Exif, Stack, Tag, User } from 'src/database';
|
import { AssetFace, AssetFile, Exif, Stack, Tag, User } from 'src/database';
|
||||||
import { PropertyLifecycle } from 'src/decorators';
|
import { HistoryBuilder, Property } from 'src/decorators';
|
||||||
import { AuthDto } from 'src/dtos/auth.dto';
|
import { AuthDto } from 'src/dtos/auth.dto';
|
||||||
import { ExifResponseDto, mapExif } from 'src/dtos/exif.dto';
|
import { ExifResponseDto, mapExif } from 'src/dtos/exif.dto';
|
||||||
import {
|
import {
|
||||||
|
|
@ -48,7 +48,7 @@ export class AssetResponseDto extends SanitizedAssetResponseDto {
|
||||||
deviceId!: string;
|
deviceId!: string;
|
||||||
ownerId!: string;
|
ownerId!: string;
|
||||||
owner?: UserResponseDto;
|
owner?: UserResponseDto;
|
||||||
@PropertyLifecycle({ deprecatedAt: 'v1.106.0' })
|
@Property({ history: new HistoryBuilder().added('v1').deprecated('v1') })
|
||||||
libraryId?: string | null;
|
libraryId?: string | null;
|
||||||
originalPath!: string;
|
originalPath!: string;
|
||||||
originalFileName!: string;
|
originalFileName!: string;
|
||||||
|
|
@ -91,7 +91,7 @@ export class AssetResponseDto extends SanitizedAssetResponseDto {
|
||||||
stack?: AssetStackResponseDto | null;
|
stack?: AssetStackResponseDto | null;
|
||||||
duplicateId?: string | null;
|
duplicateId?: string | null;
|
||||||
|
|
||||||
@PropertyLifecycle({ deprecatedAt: 'v1.113.0' })
|
@Property({ history: new HistoryBuilder().added('v1').deprecated('v1.113.0') })
|
||||||
resized?: boolean;
|
resized?: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,7 @@ import { IsArray, IsInt, IsNotEmpty, IsNumber, IsString, Max, Min, ValidateNeste
|
||||||
import { Selectable } from 'kysely';
|
import { Selectable } from 'kysely';
|
||||||
import { DateTime } from 'luxon';
|
import { DateTime } from 'luxon';
|
||||||
import { AssetFace, Person } from 'src/database';
|
import { AssetFace, Person } from 'src/database';
|
||||||
import { PropertyLifecycle } from 'src/decorators';
|
import { HistoryBuilder, Property } from 'src/decorators';
|
||||||
import { AuthDto } from 'src/dtos/auth.dto';
|
import { AuthDto } from 'src/dtos/auth.dto';
|
||||||
import { SourceType } from 'src/enum';
|
import { SourceType } from 'src/enum';
|
||||||
import { AssetFaceTable } from 'src/schema/tables/asset-face.table';
|
import { AssetFaceTable } from 'src/schema/tables/asset-face.table';
|
||||||
|
|
@ -111,11 +111,11 @@ export class PersonResponseDto {
|
||||||
birthDate!: string | null;
|
birthDate!: string | null;
|
||||||
thumbnailPath!: string;
|
thumbnailPath!: string;
|
||||||
isHidden!: boolean;
|
isHidden!: boolean;
|
||||||
@PropertyLifecycle({ addedAt: 'v1.107.0' })
|
@Property({ history: new HistoryBuilder().added('v1.107.0').stable('v2') })
|
||||||
updatedAt?: Date;
|
updatedAt?: Date;
|
||||||
@PropertyLifecycle({ addedAt: 'v1.126.0' })
|
@Property({ history: new HistoryBuilder().added('v1.126.0').stable('v2') })
|
||||||
isFavorite?: boolean;
|
isFavorite?: boolean;
|
||||||
@PropertyLifecycle({ addedAt: 'v1.126.0' })
|
@Property({ history: new HistoryBuilder().added('v1.126.0').stable('v2') })
|
||||||
color?: string;
|
color?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -216,7 +216,7 @@ export class PeopleResponseDto {
|
||||||
people!: PersonResponseDto[];
|
people!: PersonResponseDto[];
|
||||||
|
|
||||||
// TODO: make required after a few versions
|
// TODO: make required after a few versions
|
||||||
@PropertyLifecycle({ addedAt: 'v1.110.0' })
|
@Property({ history: new HistoryBuilder().added('v1.110.0').stable('v2') })
|
||||||
hasNextPage?: boolean;
|
hasNextPage?: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,7 @@ import { ApiProperty } from '@nestjs/swagger';
|
||||||
import { Type } from 'class-transformer';
|
import { Type } from 'class-transformer';
|
||||||
import { IsInt, IsNotEmpty, IsString, Max, Min } from 'class-validator';
|
import { IsInt, IsNotEmpty, IsString, Max, Min } from 'class-validator';
|
||||||
import { Place } from 'src/database';
|
import { Place } from 'src/database';
|
||||||
import { PropertyLifecycle } from 'src/decorators';
|
import { HistoryBuilder, Property } from 'src/decorators';
|
||||||
import { AlbumResponseDto } from 'src/dtos/album.dto';
|
import { AlbumResponseDto } from 'src/dtos/album.dto';
|
||||||
import { AssetResponseDto } from 'src/dtos/asset-response.dto';
|
import { AssetResponseDto } from 'src/dtos/asset-response.dto';
|
||||||
import { AssetOrder, AssetType, AssetVisibility } from 'src/enum';
|
import { AssetOrder, AssetType, AssetVisibility } from 'src/enum';
|
||||||
|
|
@ -282,7 +282,7 @@ export class SearchSuggestionRequestDto {
|
||||||
lensModel?: string;
|
lensModel?: string;
|
||||||
|
|
||||||
@ValidateBoolean({ optional: true })
|
@ValidateBoolean({ optional: true })
|
||||||
@PropertyLifecycle({ addedAt: 'v111.0.0' })
|
@Property({ history: new HistoryBuilder().added('v1.111.0').stable('v2') })
|
||||||
includeNull?: boolean;
|
includeNull?: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -434,6 +434,8 @@ export enum LogLevel {
|
||||||
export enum ApiCustomExtension {
|
export enum ApiCustomExtension {
|
||||||
Permission = 'x-immich-permission',
|
Permission = 'x-immich-permission',
|
||||||
AdminOnly = 'x-immich-admin-only',
|
AdminOnly = 'x-immich-admin-only',
|
||||||
|
History = 'x-immich-history',
|
||||||
|
State = 'x-immich-state',
|
||||||
}
|
}
|
||||||
|
|
||||||
export enum MetadataKey {
|
export enum MetadataKey {
|
||||||
|
|
|
||||||
|
|
@ -1,91 +0,0 @@
|
||||||
#!/usr/bin/env node
|
|
||||||
import { OpenAPIObject } from '@nestjs/swagger';
|
|
||||||
import { SchemaObject } from '@nestjs/swagger/dist/interfaces/open-api-spec.interface';
|
|
||||||
import { readFileSync } from 'node:fs';
|
|
||||||
import { resolve } from 'node:path';
|
|
||||||
import { SemVer } from 'semver';
|
|
||||||
import { ADDED_IN_PREFIX, DEPRECATED_IN_PREFIX, LIFECYCLE_EXTENSION, NEXT_RELEASE } from 'src/constants';
|
|
||||||
|
|
||||||
const outputPath = resolve(process.cwd(), '../open-api/immich-openapi-specs.json');
|
|
||||||
const spec = JSON.parse(readFileSync(outputPath).toString()) as OpenAPIObject;
|
|
||||||
|
|
||||||
type Items = {
|
|
||||||
oldEndpoints: Endpoint[];
|
|
||||||
newEndpoints: Endpoint[];
|
|
||||||
oldProperties: Property[];
|
|
||||||
newProperties: Property[];
|
|
||||||
};
|
|
||||||
type Endpoint = { url: string; method: string; endpoint: any };
|
|
||||||
type Property = { schema: string; property: string };
|
|
||||||
|
|
||||||
const metadata: Record<string, Items> = {};
|
|
||||||
const trackVersion = (version: string) => {
|
|
||||||
if (!metadata[version]) {
|
|
||||||
metadata[version] = {
|
|
||||||
oldEndpoints: [],
|
|
||||||
newEndpoints: [],
|
|
||||||
oldProperties: [],
|
|
||||||
newProperties: [],
|
|
||||||
};
|
|
||||||
}
|
|
||||||
return metadata[version];
|
|
||||||
};
|
|
||||||
|
|
||||||
for (const [url, methods] of Object.entries(spec.paths)) {
|
|
||||||
for (const [method, endpoint] of Object.entries(methods) as Array<[string, any]>) {
|
|
||||||
const deprecatedAt = endpoint[LIFECYCLE_EXTENSION]?.deprecatedAt;
|
|
||||||
if (deprecatedAt) {
|
|
||||||
trackVersion(deprecatedAt).oldEndpoints.push({ url, method, endpoint });
|
|
||||||
}
|
|
||||||
|
|
||||||
const addedAt = endpoint[LIFECYCLE_EXTENSION]?.addedAt;
|
|
||||||
if (addedAt) {
|
|
||||||
trackVersion(addedAt).newEndpoints.push({ url, method, endpoint });
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for (const [schemaName, schema] of Object.entries(spec.components?.schemas || {})) {
|
|
||||||
for (const [propertyName, property] of Object.entries((schema as SchemaObject).properties || {})) {
|
|
||||||
const propertySchema = property as SchemaObject;
|
|
||||||
if (propertySchema.description?.startsWith(DEPRECATED_IN_PREFIX)) {
|
|
||||||
const deprecatedAt = propertySchema.description.replace(DEPRECATED_IN_PREFIX, '').trim();
|
|
||||||
trackVersion(deprecatedAt).oldProperties.push({ schema: schemaName, property: propertyName });
|
|
||||||
}
|
|
||||||
|
|
||||||
if (propertySchema.description?.startsWith(ADDED_IN_PREFIX)) {
|
|
||||||
const addedAt = propertySchema.description.replace(ADDED_IN_PREFIX, '').trim();
|
|
||||||
trackVersion(addedAt).newProperties.push({ schema: schemaName, property: propertyName });
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const sortedVersions = Object.keys(metadata).sort((a, b) => {
|
|
||||||
if (a === NEXT_RELEASE) {
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (b === NEXT_RELEASE) {
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
return new SemVer(b).compare(new SemVer(a));
|
|
||||||
});
|
|
||||||
|
|
||||||
for (const version of sortedVersions) {
|
|
||||||
const { oldEndpoints, newEndpoints, oldProperties, newProperties } = metadata[version];
|
|
||||||
console.log(`\nChanges in ${version}`);
|
|
||||||
console.log('---------------------');
|
|
||||||
for (const { url, method, endpoint } of oldEndpoints) {
|
|
||||||
console.log(`- Deprecated ${method.toUpperCase()} ${url} (${endpoint.operationId})`);
|
|
||||||
}
|
|
||||||
for (const { url, method, endpoint } of newEndpoints) {
|
|
||||||
console.log(`- Added ${method.toUpperCase()} ${url} (${endpoint.operationId})`);
|
|
||||||
}
|
|
||||||
for (const { schema, property } of oldProperties) {
|
|
||||||
console.log(`- Deprecated ${schema}.${property}`);
|
|
||||||
}
|
|
||||||
for (const { schema, property } of newProperties) {
|
|
||||||
console.log(`- Added ${schema}.${property}`);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue