mirror of
				https://github.com/immich-app/immich.git
				synced 2025-11-03 19:17:11 -05:00 
			
		
		
		
	refactor: migrate shared-link repository to kysely (#15289)
* refactor: migrate shared-link repository to kysely * fix duplicate individual shared link return in getAll when there are more than 1 asset in the shared link * using correct order condition * using eb.table --------- Co-authored-by: Alex Tran <alex.tran1502@gmail.com>
This commit is contained in:
		
							parent
							
								
									430d0b86ee
								
							
						
					
					
						commit
						3d13da7f11
					
				@ -170,7 +170,7 @@ describe('/shared-links', () => {
 | 
				
			|||||||
      expect(status).toBe(200);
 | 
					      expect(status).toBe(200);
 | 
				
			||||||
      expect(body).toEqual(
 | 
					      expect(body).toEqual(
 | 
				
			||||||
        expect.objectContaining({
 | 
					        expect.objectContaining({
 | 
				
			||||||
          album,
 | 
					          album: expect.objectContaining({ id: album.id }),
 | 
				
			||||||
          userId: user1.userId,
 | 
					          userId: user1.userId,
 | 
				
			||||||
          type: SharedLinkType.Album,
 | 
					          type: SharedLinkType.Album,
 | 
				
			||||||
        }),
 | 
					        }),
 | 
				
			||||||
@ -208,7 +208,7 @@ describe('/shared-links', () => {
 | 
				
			|||||||
      expect(status).toBe(200);
 | 
					      expect(status).toBe(200);
 | 
				
			||||||
      expect(body).toEqual(
 | 
					      expect(body).toEqual(
 | 
				
			||||||
        expect.objectContaining({
 | 
					        expect.objectContaining({
 | 
				
			||||||
          album,
 | 
					          album: expect.objectContaining({ id: album.id }),
 | 
				
			||||||
          userId: user1.userId,
 | 
					          userId: user1.userId,
 | 
				
			||||||
          type: SharedLinkType.Album,
 | 
					          type: SharedLinkType.Album,
 | 
				
			||||||
        }),
 | 
					        }),
 | 
				
			||||||
@ -262,7 +262,7 @@ describe('/shared-links', () => {
 | 
				
			|||||||
      expect(status).toBe(200);
 | 
					      expect(status).toBe(200);
 | 
				
			||||||
      expect(body).toEqual(
 | 
					      expect(body).toEqual(
 | 
				
			||||||
        expect.objectContaining({
 | 
					        expect.objectContaining({
 | 
				
			||||||
          album,
 | 
					          album: expect.objectContaining({ id: album.id }),
 | 
				
			||||||
          userId: user1.userId,
 | 
					          userId: user1.userId,
 | 
				
			||||||
          type: SharedLinkType.Album,
 | 
					          type: SharedLinkType.Album,
 | 
				
			||||||
        }),
 | 
					        }),
 | 
				
			||||||
 | 
				
			|||||||
@ -1,12 +1,14 @@
 | 
				
			|||||||
 | 
					import { Insertable, Updateable } from 'kysely';
 | 
				
			||||||
 | 
					import { SharedLinks } from 'src/db';
 | 
				
			||||||
import { SharedLinkEntity } from 'src/entities/shared-link.entity';
 | 
					import { SharedLinkEntity } from 'src/entities/shared-link.entity';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export const ISharedLinkRepository = 'ISharedLinkRepository';
 | 
					export const ISharedLinkRepository = 'ISharedLinkRepository';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export interface ISharedLinkRepository {
 | 
					export interface ISharedLinkRepository {
 | 
				
			||||||
  getAll(userId: string): Promise<SharedLinkEntity[]>;
 | 
					  getAll(userId: string): Promise<SharedLinkEntity[]>;
 | 
				
			||||||
  get(userId: string, id: string): Promise<SharedLinkEntity | null>;
 | 
					  get(userId: string, id: string): Promise<SharedLinkEntity | undefined>;
 | 
				
			||||||
  getByKey(key: Buffer): Promise<SharedLinkEntity | null>;
 | 
					  getByKey(key: Buffer): Promise<SharedLinkEntity | undefined>;
 | 
				
			||||||
  create(entity: Partial<SharedLinkEntity>): Promise<SharedLinkEntity>;
 | 
					  create(entity: Insertable<SharedLinks> & { assetIds?: string[] }): Promise<SharedLinkEntity>;
 | 
				
			||||||
  update(entity: Partial<SharedLinkEntity>): Promise<SharedLinkEntity>;
 | 
					  update(entity: Updateable<SharedLinks> & { id: string; assetIds?: string[] }): Promise<SharedLinkEntity>;
 | 
				
			||||||
  remove(entity: SharedLinkEntity): Promise<void>;
 | 
					  remove(entity: SharedLinkEntity): Promise<void>;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -1,331 +1,197 @@
 | 
				
			|||||||
-- NOTE: This file is auto generated by ./sql-generator
 | 
					-- NOTE: This file is auto generated by ./sql-generator
 | 
				
			||||||
 | 
					
 | 
				
			||||||
-- SharedLinkRepository.get
 | 
					-- SharedLinkRepository.get
 | 
				
			||||||
SELECT DISTINCT
 | 
					select
 | 
				
			||||||
  "distinctAlias"."SharedLinkEntity_id" AS "ids_SharedLinkEntity_id",
 | 
					  "shared_links".*,
 | 
				
			||||||
  "distinctAlias"."SharedLinkEntity_createdAt",
 | 
					  coalesce(
 | 
				
			||||||
  "distinctAlias"."SharedLinkEntity__SharedLinkEntity_assets_fileCreatedAt",
 | 
					    json_agg("a") filter (
 | 
				
			||||||
  "distinctAlias"."4a35f463ae8c5544ede95c4b6d9ce8c686b6bfe6_fileCreatedAt"
 | 
					      where
 | 
				
			||||||
FROM
 | 
					        "a"."id" is not null
 | 
				
			||||||
  (
 | 
					    ),
 | 
				
			||||||
    SELECT
 | 
					    '[]'
 | 
				
			||||||
      "SharedLinkEntity"."id" AS "SharedLinkEntity_id",
 | 
					  ) as "assets",
 | 
				
			||||||
      "SharedLinkEntity"."description" AS "SharedLinkEntity_description",
 | 
					  to_json("album") as "album"
 | 
				
			||||||
      "SharedLinkEntity"."password" AS "SharedLinkEntity_password",
 | 
					from
 | 
				
			||||||
      "SharedLinkEntity"."userId" AS "SharedLinkEntity_userId",
 | 
					  "shared_links"
 | 
				
			||||||
      "SharedLinkEntity"."key" AS "SharedLinkEntity_key",
 | 
					  left join lateral (
 | 
				
			||||||
      "SharedLinkEntity"."type" AS "SharedLinkEntity_type",
 | 
					    select
 | 
				
			||||||
      "SharedLinkEntity"."createdAt" AS "SharedLinkEntity_createdAt",
 | 
					      "assets".*,
 | 
				
			||||||
      "SharedLinkEntity"."expiresAt" AS "SharedLinkEntity_expiresAt",
 | 
					      to_json("exifInfo") as "exifInfo"
 | 
				
			||||||
      "SharedLinkEntity"."allowUpload" AS "SharedLinkEntity_allowUpload",
 | 
					    from
 | 
				
			||||||
      "SharedLinkEntity"."allowDownload" AS "SharedLinkEntity_allowDownload",
 | 
					      "shared_link__asset"
 | 
				
			||||||
      "SharedLinkEntity"."showExif" AS "SharedLinkEntity_showExif",
 | 
					      inner join "assets" on "assets"."id" = "shared_link__asset"."assetsId"
 | 
				
			||||||
      "SharedLinkEntity"."albumId" AS "SharedLinkEntity_albumId",
 | 
					      inner join lateral (
 | 
				
			||||||
      "SharedLinkEntity__SharedLinkEntity_assets"."id" AS "SharedLinkEntity__SharedLinkEntity_assets_id",
 | 
					        select
 | 
				
			||||||
      "SharedLinkEntity__SharedLinkEntity_assets"."deviceAssetId" AS "SharedLinkEntity__SharedLinkEntity_assets_deviceAssetId",
 | 
					          "exif".*
 | 
				
			||||||
      "SharedLinkEntity__SharedLinkEntity_assets"."ownerId" AS "SharedLinkEntity__SharedLinkEntity_assets_ownerId",
 | 
					        from
 | 
				
			||||||
      "SharedLinkEntity__SharedLinkEntity_assets"."libraryId" AS "SharedLinkEntity__SharedLinkEntity_assets_libraryId",
 | 
					          "exif"
 | 
				
			||||||
      "SharedLinkEntity__SharedLinkEntity_assets"."deviceId" AS "SharedLinkEntity__SharedLinkEntity_assets_deviceId",
 | 
					        where
 | 
				
			||||||
      "SharedLinkEntity__SharedLinkEntity_assets"."type" AS "SharedLinkEntity__SharedLinkEntity_assets_type",
 | 
					          "exif"."assetId" = "assets"."id"
 | 
				
			||||||
      "SharedLinkEntity__SharedLinkEntity_assets"."status" AS "SharedLinkEntity__SharedLinkEntity_assets_status",
 | 
					      ) as "exifInfo" on true
 | 
				
			||||||
      "SharedLinkEntity__SharedLinkEntity_assets"."originalPath" AS "SharedLinkEntity__SharedLinkEntity_assets_originalPath",
 | 
					    where
 | 
				
			||||||
      "SharedLinkEntity__SharedLinkEntity_assets"."thumbhash" AS "SharedLinkEntity__SharedLinkEntity_assets_thumbhash",
 | 
					      "shared_links"."id" = "shared_link__asset"."sharedLinksId"
 | 
				
			||||||
      "SharedLinkEntity__SharedLinkEntity_assets"."encodedVideoPath" AS "SharedLinkEntity__SharedLinkEntity_assets_encodedVideoPath",
 | 
					      and "assets"."deletedAt" is null
 | 
				
			||||||
      "SharedLinkEntity__SharedLinkEntity_assets"."createdAt" AS "SharedLinkEntity__SharedLinkEntity_assets_createdAt",
 | 
					    order by
 | 
				
			||||||
      "SharedLinkEntity__SharedLinkEntity_assets"."updatedAt" AS "SharedLinkEntity__SharedLinkEntity_assets_updatedAt",
 | 
					      "assets"."fileCreatedAt" asc
 | 
				
			||||||
      "SharedLinkEntity__SharedLinkEntity_assets"."deletedAt" AS "SharedLinkEntity__SharedLinkEntity_assets_deletedAt",
 | 
					  ) as "a" on true
 | 
				
			||||||
      "SharedLinkEntity__SharedLinkEntity_assets"."fileCreatedAt" AS "SharedLinkEntity__SharedLinkEntity_assets_fileCreatedAt",
 | 
					  left join lateral (
 | 
				
			||||||
      "SharedLinkEntity__SharedLinkEntity_assets"."localDateTime" AS "SharedLinkEntity__SharedLinkEntity_assets_localDateTime",
 | 
					    select
 | 
				
			||||||
      "SharedLinkEntity__SharedLinkEntity_assets"."fileModifiedAt" AS "SharedLinkEntity__SharedLinkEntity_assets_fileModifiedAt",
 | 
					      "albums".*,
 | 
				
			||||||
      "SharedLinkEntity__SharedLinkEntity_assets"."isFavorite" AS "SharedLinkEntity__SharedLinkEntity_assets_isFavorite",
 | 
					      coalesce(
 | 
				
			||||||
      "SharedLinkEntity__SharedLinkEntity_assets"."isArchived" AS "SharedLinkEntity__SharedLinkEntity_assets_isArchived",
 | 
					        json_agg("assets") filter (
 | 
				
			||||||
      "SharedLinkEntity__SharedLinkEntity_assets"."isExternal" AS "SharedLinkEntity__SharedLinkEntity_assets_isExternal",
 | 
					          where
 | 
				
			||||||
      "SharedLinkEntity__SharedLinkEntity_assets"."isOffline" AS "SharedLinkEntity__SharedLinkEntity_assets_isOffline",
 | 
					            "assets"."id" is not null
 | 
				
			||||||
      "SharedLinkEntity__SharedLinkEntity_assets"."checksum" AS "SharedLinkEntity__SharedLinkEntity_assets_checksum",
 | 
					        ),
 | 
				
			||||||
      "SharedLinkEntity__SharedLinkEntity_assets"."duration" AS "SharedLinkEntity__SharedLinkEntity_assets_duration",
 | 
					        '[]'
 | 
				
			||||||
      "SharedLinkEntity__SharedLinkEntity_assets"."isVisible" AS "SharedLinkEntity__SharedLinkEntity_assets_isVisible",
 | 
					      ) as "assets",
 | 
				
			||||||
      "SharedLinkEntity__SharedLinkEntity_assets"."livePhotoVideoId" AS "SharedLinkEntity__SharedLinkEntity_assets_livePhotoVideoId",
 | 
					      to_json("owner") as "owner"
 | 
				
			||||||
      "SharedLinkEntity__SharedLinkEntity_assets"."originalFileName" AS "SharedLinkEntity__SharedLinkEntity_assets_originalFileName",
 | 
					    from
 | 
				
			||||||
      "SharedLinkEntity__SharedLinkEntity_assets"."sidecarPath" AS "SharedLinkEntity__SharedLinkEntity_assets_sidecarPath",
 | 
					      "albums"
 | 
				
			||||||
      "SharedLinkEntity__SharedLinkEntity_assets"."stackId" AS "SharedLinkEntity__SharedLinkEntity_assets_stackId",
 | 
					      left join "albums_assets_assets" on "albums_assets_assets"."albumsId" = "albums"."id"
 | 
				
			||||||
      "SharedLinkEntity__SharedLinkEntity_assets"."duplicateId" AS "SharedLinkEntity__SharedLinkEntity_assets_duplicateId",
 | 
					      left join lateral (
 | 
				
			||||||
      "9b1d35b344d838023994a3233afd6ffe098be6d8"."assetId" AS "9b1d35b344d838023994a3233afd6ffe098be6d8_assetId",
 | 
					        select
 | 
				
			||||||
      "9b1d35b344d838023994a3233afd6ffe098be6d8"."description" AS "9b1d35b344d838023994a3233afd6ffe098be6d8_description",
 | 
					          "assets".*,
 | 
				
			||||||
      "9b1d35b344d838023994a3233afd6ffe098be6d8"."exifImageWidth" AS "9b1d35b344d838023994a3233afd6ffe098be6d8_exifImageWidth",
 | 
					          to_json("assets_exifInfo") as "exifInfo"
 | 
				
			||||||
      "9b1d35b344d838023994a3233afd6ffe098be6d8"."exifImageHeight" AS "9b1d35b344d838023994a3233afd6ffe098be6d8_exifImageHeight",
 | 
					        from
 | 
				
			||||||
      "9b1d35b344d838023994a3233afd6ffe098be6d8"."fileSizeInByte" AS "9b1d35b344d838023994a3233afd6ffe098be6d8_fileSizeInByte",
 | 
					          "assets"
 | 
				
			||||||
      "9b1d35b344d838023994a3233afd6ffe098be6d8"."orientation" AS "9b1d35b344d838023994a3233afd6ffe098be6d8_orientation",
 | 
					          inner join lateral (
 | 
				
			||||||
      "9b1d35b344d838023994a3233afd6ffe098be6d8"."dateTimeOriginal" AS "9b1d35b344d838023994a3233afd6ffe098be6d8_dateTimeOriginal",
 | 
					            select
 | 
				
			||||||
      "9b1d35b344d838023994a3233afd6ffe098be6d8"."modifyDate" AS "9b1d35b344d838023994a3233afd6ffe098be6d8_modifyDate",
 | 
					              "exif".*
 | 
				
			||||||
      "9b1d35b344d838023994a3233afd6ffe098be6d8"."timeZone" AS "9b1d35b344d838023994a3233afd6ffe098be6d8_timeZone",
 | 
					            from
 | 
				
			||||||
      "9b1d35b344d838023994a3233afd6ffe098be6d8"."latitude" AS "9b1d35b344d838023994a3233afd6ffe098be6d8_latitude",
 | 
					              "exif"
 | 
				
			||||||
      "9b1d35b344d838023994a3233afd6ffe098be6d8"."longitude" AS "9b1d35b344d838023994a3233afd6ffe098be6d8_longitude",
 | 
					            where
 | 
				
			||||||
      "9b1d35b344d838023994a3233afd6ffe098be6d8"."projectionType" AS "9b1d35b344d838023994a3233afd6ffe098be6d8_projectionType",
 | 
					              "exif"."assetId" = "assets"."id"
 | 
				
			||||||
      "9b1d35b344d838023994a3233afd6ffe098be6d8"."city" AS "9b1d35b344d838023994a3233afd6ffe098be6d8_city",
 | 
					          ) as "assets_exifInfo" on true
 | 
				
			||||||
      "9b1d35b344d838023994a3233afd6ffe098be6d8"."livePhotoCID" AS "9b1d35b344d838023994a3233afd6ffe098be6d8_livePhotoCID",
 | 
					        where
 | 
				
			||||||
      "9b1d35b344d838023994a3233afd6ffe098be6d8"."autoStackId" AS "9b1d35b344d838023994a3233afd6ffe098be6d8_autoStackId",
 | 
					          "albums_assets_assets"."assetsId" = "assets"."id"
 | 
				
			||||||
      "9b1d35b344d838023994a3233afd6ffe098be6d8"."state" AS "9b1d35b344d838023994a3233afd6ffe098be6d8_state",
 | 
					          and "assets"."deletedAt" is null
 | 
				
			||||||
      "9b1d35b344d838023994a3233afd6ffe098be6d8"."country" AS "9b1d35b344d838023994a3233afd6ffe098be6d8_country",
 | 
					        order by
 | 
				
			||||||
      "9b1d35b344d838023994a3233afd6ffe098be6d8"."make" AS "9b1d35b344d838023994a3233afd6ffe098be6d8_make",
 | 
					          "assets"."fileCreatedAt" asc
 | 
				
			||||||
      "9b1d35b344d838023994a3233afd6ffe098be6d8"."model" AS "9b1d35b344d838023994a3233afd6ffe098be6d8_model",
 | 
					      ) as "assets" on true
 | 
				
			||||||
      "9b1d35b344d838023994a3233afd6ffe098be6d8"."lensModel" AS "9b1d35b344d838023994a3233afd6ffe098be6d8_lensModel",
 | 
					      inner join lateral (
 | 
				
			||||||
      "9b1d35b344d838023994a3233afd6ffe098be6d8"."fNumber" AS "9b1d35b344d838023994a3233afd6ffe098be6d8_fNumber",
 | 
					        select
 | 
				
			||||||
      "9b1d35b344d838023994a3233afd6ffe098be6d8"."focalLength" AS "9b1d35b344d838023994a3233afd6ffe098be6d8_focalLength",
 | 
					          "users".*
 | 
				
			||||||
      "9b1d35b344d838023994a3233afd6ffe098be6d8"."iso" AS "9b1d35b344d838023994a3233afd6ffe098be6d8_iso",
 | 
					        from
 | 
				
			||||||
      "9b1d35b344d838023994a3233afd6ffe098be6d8"."exposureTime" AS "9b1d35b344d838023994a3233afd6ffe098be6d8_exposureTime",
 | 
					          "users"
 | 
				
			||||||
      "9b1d35b344d838023994a3233afd6ffe098be6d8"."profileDescription" AS "9b1d35b344d838023994a3233afd6ffe098be6d8_profileDescription",
 | 
					        where
 | 
				
			||||||
      "9b1d35b344d838023994a3233afd6ffe098be6d8"."colorspace" AS "9b1d35b344d838023994a3233afd6ffe098be6d8_colorspace",
 | 
					          "users"."id" = "albums"."ownerId"
 | 
				
			||||||
      "9b1d35b344d838023994a3233afd6ffe098be6d8"."bitsPerSample" AS "9b1d35b344d838023994a3233afd6ffe098be6d8_bitsPerSample",
 | 
					          and "users"."deletedAt" is null
 | 
				
			||||||
      "9b1d35b344d838023994a3233afd6ffe098be6d8"."rating" AS "9b1d35b344d838023994a3233afd6ffe098be6d8_rating",
 | 
					      ) as "owner" on true
 | 
				
			||||||
      "9b1d35b344d838023994a3233afd6ffe098be6d8"."fps" AS "9b1d35b344d838023994a3233afd6ffe098be6d8_fps",
 | 
					    where
 | 
				
			||||||
      "SharedLinkEntity__SharedLinkEntity_album"."id" AS "SharedLinkEntity__SharedLinkEntity_album_id",
 | 
					      "albums"."id" = "shared_links"."albumId"
 | 
				
			||||||
      "SharedLinkEntity__SharedLinkEntity_album"."ownerId" AS "SharedLinkEntity__SharedLinkEntity_album_ownerId",
 | 
					      and "albums"."deletedAt" is null
 | 
				
			||||||
      "SharedLinkEntity__SharedLinkEntity_album"."albumName" AS "SharedLinkEntity__SharedLinkEntity_album_albumName",
 | 
					    group by
 | 
				
			||||||
      "SharedLinkEntity__SharedLinkEntity_album"."description" AS "SharedLinkEntity__SharedLinkEntity_album_description",
 | 
					      "albums"."id",
 | 
				
			||||||
      "SharedLinkEntity__SharedLinkEntity_album"."createdAt" AS "SharedLinkEntity__SharedLinkEntity_album_createdAt",
 | 
					      "owner".*
 | 
				
			||||||
      "SharedLinkEntity__SharedLinkEntity_album"."updatedAt" AS "SharedLinkEntity__SharedLinkEntity_album_updatedAt",
 | 
					  ) as "album" on true
 | 
				
			||||||
      "SharedLinkEntity__SharedLinkEntity_album"."deletedAt" AS "SharedLinkEntity__SharedLinkEntity_album_deletedAt",
 | 
					where
 | 
				
			||||||
      "SharedLinkEntity__SharedLinkEntity_album"."albumThumbnailAssetId" AS "SharedLinkEntity__SharedLinkEntity_album_albumThumbnailAssetId",
 | 
					  "shared_links"."id" = $1
 | 
				
			||||||
      "SharedLinkEntity__SharedLinkEntity_album"."isActivityEnabled" AS "SharedLinkEntity__SharedLinkEntity_album_isActivityEnabled",
 | 
					  and "shared_links"."userId" = $2
 | 
				
			||||||
      "SharedLinkEntity__SharedLinkEntity_album"."order" AS "SharedLinkEntity__SharedLinkEntity_album_order",
 | 
					  and (
 | 
				
			||||||
      "4a35f463ae8c5544ede95c4b6d9ce8c686b6bfe6"."id" AS "4a35f463ae8c5544ede95c4b6d9ce8c686b6bfe6_id",
 | 
					    "shared_links"."type" = $3
 | 
				
			||||||
      "4a35f463ae8c5544ede95c4b6d9ce8c686b6bfe6"."deviceAssetId" AS "4a35f463ae8c5544ede95c4b6d9ce8c686b6bfe6_deviceAssetId",
 | 
					    or "album"."id" is not null
 | 
				
			||||||
      "4a35f463ae8c5544ede95c4b6d9ce8c686b6bfe6"."ownerId" AS "4a35f463ae8c5544ede95c4b6d9ce8c686b6bfe6_ownerId",
 | 
					  )
 | 
				
			||||||
      "4a35f463ae8c5544ede95c4b6d9ce8c686b6bfe6"."libraryId" AS "4a35f463ae8c5544ede95c4b6d9ce8c686b6bfe6_libraryId",
 | 
					group by
 | 
				
			||||||
      "4a35f463ae8c5544ede95c4b6d9ce8c686b6bfe6"."deviceId" AS "4a35f463ae8c5544ede95c4b6d9ce8c686b6bfe6_deviceId",
 | 
					  "shared_links"."id",
 | 
				
			||||||
      "4a35f463ae8c5544ede95c4b6d9ce8c686b6bfe6"."type" AS "4a35f463ae8c5544ede95c4b6d9ce8c686b6bfe6_type",
 | 
					  "album".*
 | 
				
			||||||
      "4a35f463ae8c5544ede95c4b6d9ce8c686b6bfe6"."status" AS "4a35f463ae8c5544ede95c4b6d9ce8c686b6bfe6_status",
 | 
					order by
 | 
				
			||||||
      "4a35f463ae8c5544ede95c4b6d9ce8c686b6bfe6"."originalPath" AS "4a35f463ae8c5544ede95c4b6d9ce8c686b6bfe6_originalPath",
 | 
					  "shared_links"."createdAt" desc
 | 
				
			||||||
      "4a35f463ae8c5544ede95c4b6d9ce8c686b6bfe6"."thumbhash" AS "4a35f463ae8c5544ede95c4b6d9ce8c686b6bfe6_thumbhash",
 | 
					 | 
				
			||||||
      "4a35f463ae8c5544ede95c4b6d9ce8c686b6bfe6"."encodedVideoPath" AS "4a35f463ae8c5544ede95c4b6d9ce8c686b6bfe6_encodedVideoPath",
 | 
					 | 
				
			||||||
      "4a35f463ae8c5544ede95c4b6d9ce8c686b6bfe6"."createdAt" AS "4a35f463ae8c5544ede95c4b6d9ce8c686b6bfe6_createdAt",
 | 
					 | 
				
			||||||
      "4a35f463ae8c5544ede95c4b6d9ce8c686b6bfe6"."updatedAt" AS "4a35f463ae8c5544ede95c4b6d9ce8c686b6bfe6_updatedAt",
 | 
					 | 
				
			||||||
      "4a35f463ae8c5544ede95c4b6d9ce8c686b6bfe6"."deletedAt" AS "4a35f463ae8c5544ede95c4b6d9ce8c686b6bfe6_deletedAt",
 | 
					 | 
				
			||||||
      "4a35f463ae8c5544ede95c4b6d9ce8c686b6bfe6"."fileCreatedAt" AS "4a35f463ae8c5544ede95c4b6d9ce8c686b6bfe6_fileCreatedAt",
 | 
					 | 
				
			||||||
      "4a35f463ae8c5544ede95c4b6d9ce8c686b6bfe6"."localDateTime" AS "4a35f463ae8c5544ede95c4b6d9ce8c686b6bfe6_localDateTime",
 | 
					 | 
				
			||||||
      "4a35f463ae8c5544ede95c4b6d9ce8c686b6bfe6"."fileModifiedAt" AS "4a35f463ae8c5544ede95c4b6d9ce8c686b6bfe6_fileModifiedAt",
 | 
					 | 
				
			||||||
      "4a35f463ae8c5544ede95c4b6d9ce8c686b6bfe6"."isFavorite" AS "4a35f463ae8c5544ede95c4b6d9ce8c686b6bfe6_isFavorite",
 | 
					 | 
				
			||||||
      "4a35f463ae8c5544ede95c4b6d9ce8c686b6bfe6"."isArchived" AS "4a35f463ae8c5544ede95c4b6d9ce8c686b6bfe6_isArchived",
 | 
					 | 
				
			||||||
      "4a35f463ae8c5544ede95c4b6d9ce8c686b6bfe6"."isExternal" AS "4a35f463ae8c5544ede95c4b6d9ce8c686b6bfe6_isExternal",
 | 
					 | 
				
			||||||
      "4a35f463ae8c5544ede95c4b6d9ce8c686b6bfe6"."isOffline" AS "4a35f463ae8c5544ede95c4b6d9ce8c686b6bfe6_isOffline",
 | 
					 | 
				
			||||||
      "4a35f463ae8c5544ede95c4b6d9ce8c686b6bfe6"."checksum" AS "4a35f463ae8c5544ede95c4b6d9ce8c686b6bfe6_checksum",
 | 
					 | 
				
			||||||
      "4a35f463ae8c5544ede95c4b6d9ce8c686b6bfe6"."duration" AS "4a35f463ae8c5544ede95c4b6d9ce8c686b6bfe6_duration",
 | 
					 | 
				
			||||||
      "4a35f463ae8c5544ede95c4b6d9ce8c686b6bfe6"."isVisible" AS "4a35f463ae8c5544ede95c4b6d9ce8c686b6bfe6_isVisible",
 | 
					 | 
				
			||||||
      "4a35f463ae8c5544ede95c4b6d9ce8c686b6bfe6"."livePhotoVideoId" AS "4a35f463ae8c5544ede95c4b6d9ce8c686b6bfe6_livePhotoVideoId",
 | 
					 | 
				
			||||||
      "4a35f463ae8c5544ede95c4b6d9ce8c686b6bfe6"."originalFileName" AS "4a35f463ae8c5544ede95c4b6d9ce8c686b6bfe6_originalFileName",
 | 
					 | 
				
			||||||
      "4a35f463ae8c5544ede95c4b6d9ce8c686b6bfe6"."sidecarPath" AS "4a35f463ae8c5544ede95c4b6d9ce8c686b6bfe6_sidecarPath",
 | 
					 | 
				
			||||||
      "4a35f463ae8c5544ede95c4b6d9ce8c686b6bfe6"."stackId" AS "4a35f463ae8c5544ede95c4b6d9ce8c686b6bfe6_stackId",
 | 
					 | 
				
			||||||
      "4a35f463ae8c5544ede95c4b6d9ce8c686b6bfe6"."duplicateId" AS "4a35f463ae8c5544ede95c4b6d9ce8c686b6bfe6_duplicateId",
 | 
					 | 
				
			||||||
      "d9f2f4dd8920bad1d6907cdb1d699732daff3c2f"."assetId" AS "d9f2f4dd8920bad1d6907cdb1d699732daff3c2f_assetId",
 | 
					 | 
				
			||||||
      "d9f2f4dd8920bad1d6907cdb1d699732daff3c2f"."description" AS "d9f2f4dd8920bad1d6907cdb1d699732daff3c2f_description",
 | 
					 | 
				
			||||||
      "d9f2f4dd8920bad1d6907cdb1d699732daff3c2f"."exifImageWidth" AS "d9f2f4dd8920bad1d6907cdb1d699732daff3c2f_exifImageWidth",
 | 
					 | 
				
			||||||
      "d9f2f4dd8920bad1d6907cdb1d699732daff3c2f"."exifImageHeight" AS "d9f2f4dd8920bad1d6907cdb1d699732daff3c2f_exifImageHeight",
 | 
					 | 
				
			||||||
      "d9f2f4dd8920bad1d6907cdb1d699732daff3c2f"."fileSizeInByte" AS "d9f2f4dd8920bad1d6907cdb1d699732daff3c2f_fileSizeInByte",
 | 
					 | 
				
			||||||
      "d9f2f4dd8920bad1d6907cdb1d699732daff3c2f"."orientation" AS "d9f2f4dd8920bad1d6907cdb1d699732daff3c2f_orientation",
 | 
					 | 
				
			||||||
      "d9f2f4dd8920bad1d6907cdb1d699732daff3c2f"."dateTimeOriginal" AS "d9f2f4dd8920bad1d6907cdb1d699732daff3c2f_dateTimeOriginal",
 | 
					 | 
				
			||||||
      "d9f2f4dd8920bad1d6907cdb1d699732daff3c2f"."modifyDate" AS "d9f2f4dd8920bad1d6907cdb1d699732daff3c2f_modifyDate",
 | 
					 | 
				
			||||||
      "d9f2f4dd8920bad1d6907cdb1d699732daff3c2f"."timeZone" AS "d9f2f4dd8920bad1d6907cdb1d699732daff3c2f_timeZone",
 | 
					 | 
				
			||||||
      "d9f2f4dd8920bad1d6907cdb1d699732daff3c2f"."latitude" AS "d9f2f4dd8920bad1d6907cdb1d699732daff3c2f_latitude",
 | 
					 | 
				
			||||||
      "d9f2f4dd8920bad1d6907cdb1d699732daff3c2f"."longitude" AS "d9f2f4dd8920bad1d6907cdb1d699732daff3c2f_longitude",
 | 
					 | 
				
			||||||
      "d9f2f4dd8920bad1d6907cdb1d699732daff3c2f"."projectionType" AS "d9f2f4dd8920bad1d6907cdb1d699732daff3c2f_projectionType",
 | 
					 | 
				
			||||||
      "d9f2f4dd8920bad1d6907cdb1d699732daff3c2f"."city" AS "d9f2f4dd8920bad1d6907cdb1d699732daff3c2f_city",
 | 
					 | 
				
			||||||
      "d9f2f4dd8920bad1d6907cdb1d699732daff3c2f"."livePhotoCID" AS "d9f2f4dd8920bad1d6907cdb1d699732daff3c2f_livePhotoCID",
 | 
					 | 
				
			||||||
      "d9f2f4dd8920bad1d6907cdb1d699732daff3c2f"."autoStackId" AS "d9f2f4dd8920bad1d6907cdb1d699732daff3c2f_autoStackId",
 | 
					 | 
				
			||||||
      "d9f2f4dd8920bad1d6907cdb1d699732daff3c2f"."state" AS "d9f2f4dd8920bad1d6907cdb1d699732daff3c2f_state",
 | 
					 | 
				
			||||||
      "d9f2f4dd8920bad1d6907cdb1d699732daff3c2f"."country" AS "d9f2f4dd8920bad1d6907cdb1d699732daff3c2f_country",
 | 
					 | 
				
			||||||
      "d9f2f4dd8920bad1d6907cdb1d699732daff3c2f"."make" AS "d9f2f4dd8920bad1d6907cdb1d699732daff3c2f_make",
 | 
					 | 
				
			||||||
      "d9f2f4dd8920bad1d6907cdb1d699732daff3c2f"."model" AS "d9f2f4dd8920bad1d6907cdb1d699732daff3c2f_model",
 | 
					 | 
				
			||||||
      "d9f2f4dd8920bad1d6907cdb1d699732daff3c2f"."lensModel" AS "d9f2f4dd8920bad1d6907cdb1d699732daff3c2f_lensModel",
 | 
					 | 
				
			||||||
      "d9f2f4dd8920bad1d6907cdb1d699732daff3c2f"."fNumber" AS "d9f2f4dd8920bad1d6907cdb1d699732daff3c2f_fNumber",
 | 
					 | 
				
			||||||
      "d9f2f4dd8920bad1d6907cdb1d699732daff3c2f"."focalLength" AS "d9f2f4dd8920bad1d6907cdb1d699732daff3c2f_focalLength",
 | 
					 | 
				
			||||||
      "d9f2f4dd8920bad1d6907cdb1d699732daff3c2f"."iso" AS "d9f2f4dd8920bad1d6907cdb1d699732daff3c2f_iso",
 | 
					 | 
				
			||||||
      "d9f2f4dd8920bad1d6907cdb1d699732daff3c2f"."exposureTime" AS "d9f2f4dd8920bad1d6907cdb1d699732daff3c2f_exposureTime",
 | 
					 | 
				
			||||||
      "d9f2f4dd8920bad1d6907cdb1d699732daff3c2f"."profileDescription" AS "d9f2f4dd8920bad1d6907cdb1d699732daff3c2f_profileDescription",
 | 
					 | 
				
			||||||
      "d9f2f4dd8920bad1d6907cdb1d699732daff3c2f"."colorspace" AS "d9f2f4dd8920bad1d6907cdb1d699732daff3c2f_colorspace",
 | 
					 | 
				
			||||||
      "d9f2f4dd8920bad1d6907cdb1d699732daff3c2f"."bitsPerSample" AS "d9f2f4dd8920bad1d6907cdb1d699732daff3c2f_bitsPerSample",
 | 
					 | 
				
			||||||
      "d9f2f4dd8920bad1d6907cdb1d699732daff3c2f"."rating" AS "d9f2f4dd8920bad1d6907cdb1d699732daff3c2f_rating",
 | 
					 | 
				
			||||||
      "d9f2f4dd8920bad1d6907cdb1d699732daff3c2f"."fps" AS "d9f2f4dd8920bad1d6907cdb1d699732daff3c2f_fps",
 | 
					 | 
				
			||||||
      "6d7fd45329a05fd86b3dbcacde87fe76e33a422d"."id" AS "6d7fd45329a05fd86b3dbcacde87fe76e33a422d_id",
 | 
					 | 
				
			||||||
      "6d7fd45329a05fd86b3dbcacde87fe76e33a422d"."name" AS "6d7fd45329a05fd86b3dbcacde87fe76e33a422d_name",
 | 
					 | 
				
			||||||
      "6d7fd45329a05fd86b3dbcacde87fe76e33a422d"."isAdmin" AS "6d7fd45329a05fd86b3dbcacde87fe76e33a422d_isAdmin",
 | 
					 | 
				
			||||||
      "6d7fd45329a05fd86b3dbcacde87fe76e33a422d"."email" AS "6d7fd45329a05fd86b3dbcacde87fe76e33a422d_email",
 | 
					 | 
				
			||||||
      "6d7fd45329a05fd86b3dbcacde87fe76e33a422d"."storageLabel" AS "6d7fd45329a05fd86b3dbcacde87fe76e33a422d_storageLabel",
 | 
					 | 
				
			||||||
      "6d7fd45329a05fd86b3dbcacde87fe76e33a422d"."oauthId" AS "6d7fd45329a05fd86b3dbcacde87fe76e33a422d_oauthId",
 | 
					 | 
				
			||||||
      "6d7fd45329a05fd86b3dbcacde87fe76e33a422d"."profileImagePath" AS "6d7fd45329a05fd86b3dbcacde87fe76e33a422d_profileImagePath",
 | 
					 | 
				
			||||||
      "6d7fd45329a05fd86b3dbcacde87fe76e33a422d"."shouldChangePassword" AS "6d7fd45329a05fd86b3dbcacde87fe76e33a422d_shouldChangePassword",
 | 
					 | 
				
			||||||
      "6d7fd45329a05fd86b3dbcacde87fe76e33a422d"."createdAt" AS "6d7fd45329a05fd86b3dbcacde87fe76e33a422d_createdAt",
 | 
					 | 
				
			||||||
      "6d7fd45329a05fd86b3dbcacde87fe76e33a422d"."deletedAt" AS "6d7fd45329a05fd86b3dbcacde87fe76e33a422d_deletedAt",
 | 
					 | 
				
			||||||
      "6d7fd45329a05fd86b3dbcacde87fe76e33a422d"."status" AS "6d7fd45329a05fd86b3dbcacde87fe76e33a422d_status",
 | 
					 | 
				
			||||||
      "6d7fd45329a05fd86b3dbcacde87fe76e33a422d"."updatedAt" AS "6d7fd45329a05fd86b3dbcacde87fe76e33a422d_updatedAt",
 | 
					 | 
				
			||||||
      "6d7fd45329a05fd86b3dbcacde87fe76e33a422d"."quotaSizeInBytes" AS "6d7fd45329a05fd86b3dbcacde87fe76e33a422d_quotaSizeInBytes",
 | 
					 | 
				
			||||||
      "6d7fd45329a05fd86b3dbcacde87fe76e33a422d"."quotaUsageInBytes" AS "6d7fd45329a05fd86b3dbcacde87fe76e33a422d_quotaUsageInBytes",
 | 
					 | 
				
			||||||
      "6d7fd45329a05fd86b3dbcacde87fe76e33a422d"."profileChangedAt" AS "6d7fd45329a05fd86b3dbcacde87fe76e33a422d_profileChangedAt"
 | 
					 | 
				
			||||||
    FROM
 | 
					 | 
				
			||||||
      "shared_links" "SharedLinkEntity"
 | 
					 | 
				
			||||||
      LEFT JOIN "shared_link__asset" "SharedLinkEntity__SharedLinkEntity_assets_SharedLinkEntity" ON "SharedLinkEntity__SharedLinkEntity_assets_SharedLinkEntity"."sharedLinksId" = "SharedLinkEntity"."id"
 | 
					 | 
				
			||||||
      LEFT JOIN "assets" "SharedLinkEntity__SharedLinkEntity_assets" ON "SharedLinkEntity__SharedLinkEntity_assets"."id" = "SharedLinkEntity__SharedLinkEntity_assets_SharedLinkEntity"."assetsId"
 | 
					 | 
				
			||||||
      AND (
 | 
					 | 
				
			||||||
        "SharedLinkEntity__SharedLinkEntity_assets"."deletedAt" IS NULL
 | 
					 | 
				
			||||||
      )
 | 
					 | 
				
			||||||
      LEFT JOIN "exif" "9b1d35b344d838023994a3233afd6ffe098be6d8" ON "9b1d35b344d838023994a3233afd6ffe098be6d8"."assetId" = "SharedLinkEntity__SharedLinkEntity_assets"."id"
 | 
					 | 
				
			||||||
      LEFT JOIN "albums" "SharedLinkEntity__SharedLinkEntity_album" ON "SharedLinkEntity__SharedLinkEntity_album"."id" = "SharedLinkEntity"."albumId"
 | 
					 | 
				
			||||||
      AND (
 | 
					 | 
				
			||||||
        "SharedLinkEntity__SharedLinkEntity_album"."deletedAt" IS NULL
 | 
					 | 
				
			||||||
      )
 | 
					 | 
				
			||||||
      LEFT JOIN "albums_assets_assets" "760f12c00d97bdcec1ce224d1e3bf449859942b6" ON "760f12c00d97bdcec1ce224d1e3bf449859942b6"."albumsId" = "SharedLinkEntity__SharedLinkEntity_album"."id"
 | 
					 | 
				
			||||||
      LEFT JOIN "assets" "4a35f463ae8c5544ede95c4b6d9ce8c686b6bfe6" ON "4a35f463ae8c5544ede95c4b6d9ce8c686b6bfe6"."id" = "760f12c00d97bdcec1ce224d1e3bf449859942b6"."assetsId"
 | 
					 | 
				
			||||||
      AND (
 | 
					 | 
				
			||||||
        "4a35f463ae8c5544ede95c4b6d9ce8c686b6bfe6"."deletedAt" IS NULL
 | 
					 | 
				
			||||||
      )
 | 
					 | 
				
			||||||
      LEFT JOIN "exif" "d9f2f4dd8920bad1d6907cdb1d699732daff3c2f" ON "d9f2f4dd8920bad1d6907cdb1d699732daff3c2f"."assetId" = "4a35f463ae8c5544ede95c4b6d9ce8c686b6bfe6"."id"
 | 
					 | 
				
			||||||
      LEFT JOIN "users" "6d7fd45329a05fd86b3dbcacde87fe76e33a422d" ON "6d7fd45329a05fd86b3dbcacde87fe76e33a422d"."id" = "SharedLinkEntity__SharedLinkEntity_album"."ownerId"
 | 
					 | 
				
			||||||
      AND (
 | 
					 | 
				
			||||||
        "6d7fd45329a05fd86b3dbcacde87fe76e33a422d"."deletedAt" IS NULL
 | 
					 | 
				
			||||||
      )
 | 
					 | 
				
			||||||
    WHERE
 | 
					 | 
				
			||||||
      (
 | 
					 | 
				
			||||||
        ("SharedLinkEntity"."id" = $1)
 | 
					 | 
				
			||||||
        AND ("SharedLinkEntity"."userId" = $2)
 | 
					 | 
				
			||||||
      )
 | 
					 | 
				
			||||||
  ) "distinctAlias"
 | 
					 | 
				
			||||||
ORDER BY
 | 
					 | 
				
			||||||
  "distinctAlias"."SharedLinkEntity_createdAt" DESC,
 | 
					 | 
				
			||||||
  "distinctAlias"."SharedLinkEntity__SharedLinkEntity_assets_fileCreatedAt" ASC,
 | 
					 | 
				
			||||||
  "distinctAlias"."4a35f463ae8c5544ede95c4b6d9ce8c686b6bfe6_fileCreatedAt" ASC,
 | 
					 | 
				
			||||||
  "SharedLinkEntity_id" ASC
 | 
					 | 
				
			||||||
LIMIT
 | 
					 | 
				
			||||||
  1
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
-- SharedLinkRepository.getAll
 | 
					-- SharedLinkRepository.getAll
 | 
				
			||||||
SELECT
 | 
					select distinct
 | 
				
			||||||
  "SharedLinkEntity"."id" AS "SharedLinkEntity_id",
 | 
					  on ("shared_links"."createdAt") "shared_links".*,
 | 
				
			||||||
  "SharedLinkEntity"."description" AS "SharedLinkEntity_description",
 | 
					  to_json("album") as "album"
 | 
				
			||||||
  "SharedLinkEntity"."password" AS "SharedLinkEntity_password",
 | 
					from
 | 
				
			||||||
  "SharedLinkEntity"."userId" AS "SharedLinkEntity_userId",
 | 
					  "shared_links"
 | 
				
			||||||
  "SharedLinkEntity"."key" AS "SharedLinkEntity_key",
 | 
					  left join "shared_link__asset" on "shared_link__asset"."sharedLinksId" = "shared_links"."id"
 | 
				
			||||||
  "SharedLinkEntity"."type" AS "SharedLinkEntity_type",
 | 
					  left join lateral (
 | 
				
			||||||
  "SharedLinkEntity"."createdAt" AS "SharedLinkEntity_createdAt",
 | 
					    select
 | 
				
			||||||
  "SharedLinkEntity"."expiresAt" AS "SharedLinkEntity_expiresAt",
 | 
					      "assets".*
 | 
				
			||||||
  "SharedLinkEntity"."allowUpload" AS "SharedLinkEntity_allowUpload",
 | 
					    from
 | 
				
			||||||
  "SharedLinkEntity"."allowDownload" AS "SharedLinkEntity_allowDownload",
 | 
					      "assets"
 | 
				
			||||||
  "SharedLinkEntity"."showExif" AS "SharedLinkEntity_showExif",
 | 
					    where
 | 
				
			||||||
  "SharedLinkEntity"."albumId" AS "SharedLinkEntity_albumId",
 | 
					      "assets"."id" = "shared_link__asset"."assetsId"
 | 
				
			||||||
  "SharedLinkEntity__SharedLinkEntity_assets"."id" AS "SharedLinkEntity__SharedLinkEntity_assets_id",
 | 
					      and "assets"."deletedAt" is null
 | 
				
			||||||
  "SharedLinkEntity__SharedLinkEntity_assets"."deviceAssetId" AS "SharedLinkEntity__SharedLinkEntity_assets_deviceAssetId",
 | 
					  ) as "assets" on true
 | 
				
			||||||
  "SharedLinkEntity__SharedLinkEntity_assets"."ownerId" AS "SharedLinkEntity__SharedLinkEntity_assets_ownerId",
 | 
					  left join lateral (
 | 
				
			||||||
  "SharedLinkEntity__SharedLinkEntity_assets"."libraryId" AS "SharedLinkEntity__SharedLinkEntity_assets_libraryId",
 | 
					    select
 | 
				
			||||||
  "SharedLinkEntity__SharedLinkEntity_assets"."deviceId" AS "SharedLinkEntity__SharedLinkEntity_assets_deviceId",
 | 
					      "albums".*,
 | 
				
			||||||
  "SharedLinkEntity__SharedLinkEntity_assets"."type" AS "SharedLinkEntity__SharedLinkEntity_assets_type",
 | 
					      to_json("owner") as "owner"
 | 
				
			||||||
  "SharedLinkEntity__SharedLinkEntity_assets"."status" AS "SharedLinkEntity__SharedLinkEntity_assets_status",
 | 
					    from
 | 
				
			||||||
  "SharedLinkEntity__SharedLinkEntity_assets"."originalPath" AS "SharedLinkEntity__SharedLinkEntity_assets_originalPath",
 | 
					      "albums"
 | 
				
			||||||
  "SharedLinkEntity__SharedLinkEntity_assets"."thumbhash" AS "SharedLinkEntity__SharedLinkEntity_assets_thumbhash",
 | 
					      inner join lateral (
 | 
				
			||||||
  "SharedLinkEntity__SharedLinkEntity_assets"."encodedVideoPath" AS "SharedLinkEntity__SharedLinkEntity_assets_encodedVideoPath",
 | 
					        select
 | 
				
			||||||
  "SharedLinkEntity__SharedLinkEntity_assets"."createdAt" AS "SharedLinkEntity__SharedLinkEntity_assets_createdAt",
 | 
					          "users"."id",
 | 
				
			||||||
  "SharedLinkEntity__SharedLinkEntity_assets"."updatedAt" AS "SharedLinkEntity__SharedLinkEntity_assets_updatedAt",
 | 
					          "users"."email",
 | 
				
			||||||
  "SharedLinkEntity__SharedLinkEntity_assets"."deletedAt" AS "SharedLinkEntity__SharedLinkEntity_assets_deletedAt",
 | 
					          "users"."createdAt",
 | 
				
			||||||
  "SharedLinkEntity__SharedLinkEntity_assets"."fileCreatedAt" AS "SharedLinkEntity__SharedLinkEntity_assets_fileCreatedAt",
 | 
					          "users"."profileImagePath",
 | 
				
			||||||
  "SharedLinkEntity__SharedLinkEntity_assets"."localDateTime" AS "SharedLinkEntity__SharedLinkEntity_assets_localDateTime",
 | 
					          "users"."isAdmin",
 | 
				
			||||||
  "SharedLinkEntity__SharedLinkEntity_assets"."fileModifiedAt" AS "SharedLinkEntity__SharedLinkEntity_assets_fileModifiedAt",
 | 
					          "users"."shouldChangePassword",
 | 
				
			||||||
  "SharedLinkEntity__SharedLinkEntity_assets"."isFavorite" AS "SharedLinkEntity__SharedLinkEntity_assets_isFavorite",
 | 
					          "users"."deletedAt",
 | 
				
			||||||
  "SharedLinkEntity__SharedLinkEntity_assets"."isArchived" AS "SharedLinkEntity__SharedLinkEntity_assets_isArchived",
 | 
					          "users"."oauthId",
 | 
				
			||||||
  "SharedLinkEntity__SharedLinkEntity_assets"."isExternal" AS "SharedLinkEntity__SharedLinkEntity_assets_isExternal",
 | 
					          "users"."updatedAt",
 | 
				
			||||||
  "SharedLinkEntity__SharedLinkEntity_assets"."isOffline" AS "SharedLinkEntity__SharedLinkEntity_assets_isOffline",
 | 
					          "users"."storageLabel",
 | 
				
			||||||
  "SharedLinkEntity__SharedLinkEntity_assets"."checksum" AS "SharedLinkEntity__SharedLinkEntity_assets_checksum",
 | 
					          "users"."name",
 | 
				
			||||||
  "SharedLinkEntity__SharedLinkEntity_assets"."duration" AS "SharedLinkEntity__SharedLinkEntity_assets_duration",
 | 
					          "users"."quotaSizeInBytes",
 | 
				
			||||||
  "SharedLinkEntity__SharedLinkEntity_assets"."isVisible" AS "SharedLinkEntity__SharedLinkEntity_assets_isVisible",
 | 
					          "users"."quotaUsageInBytes",
 | 
				
			||||||
  "SharedLinkEntity__SharedLinkEntity_assets"."livePhotoVideoId" AS "SharedLinkEntity__SharedLinkEntity_assets_livePhotoVideoId",
 | 
					          "users"."status",
 | 
				
			||||||
  "SharedLinkEntity__SharedLinkEntity_assets"."originalFileName" AS "SharedLinkEntity__SharedLinkEntity_assets_originalFileName",
 | 
					          "users"."profileChangedAt"
 | 
				
			||||||
  "SharedLinkEntity__SharedLinkEntity_assets"."sidecarPath" AS "SharedLinkEntity__SharedLinkEntity_assets_sidecarPath",
 | 
					        from
 | 
				
			||||||
  "SharedLinkEntity__SharedLinkEntity_assets"."stackId" AS "SharedLinkEntity__SharedLinkEntity_assets_stackId",
 | 
					          "users"
 | 
				
			||||||
  "SharedLinkEntity__SharedLinkEntity_assets"."duplicateId" AS "SharedLinkEntity__SharedLinkEntity_assets_duplicateId",
 | 
					        where
 | 
				
			||||||
  "SharedLinkEntity__SharedLinkEntity_album"."id" AS "SharedLinkEntity__SharedLinkEntity_album_id",
 | 
					          "users"."id" = "albums"."ownerId"
 | 
				
			||||||
  "SharedLinkEntity__SharedLinkEntity_album"."ownerId" AS "SharedLinkEntity__SharedLinkEntity_album_ownerId",
 | 
					          and "users"."deletedAt" is null
 | 
				
			||||||
  "SharedLinkEntity__SharedLinkEntity_album"."albumName" AS "SharedLinkEntity__SharedLinkEntity_album_albumName",
 | 
					      ) as "owner" on true
 | 
				
			||||||
  "SharedLinkEntity__SharedLinkEntity_album"."description" AS "SharedLinkEntity__SharedLinkEntity_album_description",
 | 
					    where
 | 
				
			||||||
  "SharedLinkEntity__SharedLinkEntity_album"."createdAt" AS "SharedLinkEntity__SharedLinkEntity_album_createdAt",
 | 
					      "albums"."id" = "shared_links"."albumId"
 | 
				
			||||||
  "SharedLinkEntity__SharedLinkEntity_album"."updatedAt" AS "SharedLinkEntity__SharedLinkEntity_album_updatedAt",
 | 
					      and "albums"."deletedAt" is null
 | 
				
			||||||
  "SharedLinkEntity__SharedLinkEntity_album"."deletedAt" AS "SharedLinkEntity__SharedLinkEntity_album_deletedAt",
 | 
					  ) as "album" on true
 | 
				
			||||||
  "SharedLinkEntity__SharedLinkEntity_album"."albumThumbnailAssetId" AS "SharedLinkEntity__SharedLinkEntity_album_albumThumbnailAssetId",
 | 
					where
 | 
				
			||||||
  "SharedLinkEntity__SharedLinkEntity_album"."isActivityEnabled" AS "SharedLinkEntity__SharedLinkEntity_album_isActivityEnabled",
 | 
					  "shared_links"."userId" = $1
 | 
				
			||||||
  "SharedLinkEntity__SharedLinkEntity_album"."order" AS "SharedLinkEntity__SharedLinkEntity_album_order",
 | 
					  and (
 | 
				
			||||||
  "6d7fd45329a05fd86b3dbcacde87fe76e33a422d"."id" AS "6d7fd45329a05fd86b3dbcacde87fe76e33a422d_id",
 | 
					    "shared_links"."type" = $2
 | 
				
			||||||
  "6d7fd45329a05fd86b3dbcacde87fe76e33a422d"."name" AS "6d7fd45329a05fd86b3dbcacde87fe76e33a422d_name",
 | 
					    or "album"."id" is not null
 | 
				
			||||||
  "6d7fd45329a05fd86b3dbcacde87fe76e33a422d"."isAdmin" AS "6d7fd45329a05fd86b3dbcacde87fe76e33a422d_isAdmin",
 | 
					 | 
				
			||||||
  "6d7fd45329a05fd86b3dbcacde87fe76e33a422d"."email" AS "6d7fd45329a05fd86b3dbcacde87fe76e33a422d_email",
 | 
					 | 
				
			||||||
  "6d7fd45329a05fd86b3dbcacde87fe76e33a422d"."storageLabel" AS "6d7fd45329a05fd86b3dbcacde87fe76e33a422d_storageLabel",
 | 
					 | 
				
			||||||
  "6d7fd45329a05fd86b3dbcacde87fe76e33a422d"."oauthId" AS "6d7fd45329a05fd86b3dbcacde87fe76e33a422d_oauthId",
 | 
					 | 
				
			||||||
  "6d7fd45329a05fd86b3dbcacde87fe76e33a422d"."profileImagePath" AS "6d7fd45329a05fd86b3dbcacde87fe76e33a422d_profileImagePath",
 | 
					 | 
				
			||||||
  "6d7fd45329a05fd86b3dbcacde87fe76e33a422d"."shouldChangePassword" AS "6d7fd45329a05fd86b3dbcacde87fe76e33a422d_shouldChangePassword",
 | 
					 | 
				
			||||||
  "6d7fd45329a05fd86b3dbcacde87fe76e33a422d"."createdAt" AS "6d7fd45329a05fd86b3dbcacde87fe76e33a422d_createdAt",
 | 
					 | 
				
			||||||
  "6d7fd45329a05fd86b3dbcacde87fe76e33a422d"."deletedAt" AS "6d7fd45329a05fd86b3dbcacde87fe76e33a422d_deletedAt",
 | 
					 | 
				
			||||||
  "6d7fd45329a05fd86b3dbcacde87fe76e33a422d"."status" AS "6d7fd45329a05fd86b3dbcacde87fe76e33a422d_status",
 | 
					 | 
				
			||||||
  "6d7fd45329a05fd86b3dbcacde87fe76e33a422d"."updatedAt" AS "6d7fd45329a05fd86b3dbcacde87fe76e33a422d_updatedAt",
 | 
					 | 
				
			||||||
  "6d7fd45329a05fd86b3dbcacde87fe76e33a422d"."quotaSizeInBytes" AS "6d7fd45329a05fd86b3dbcacde87fe76e33a422d_quotaSizeInBytes",
 | 
					 | 
				
			||||||
  "6d7fd45329a05fd86b3dbcacde87fe76e33a422d"."quotaUsageInBytes" AS "6d7fd45329a05fd86b3dbcacde87fe76e33a422d_quotaUsageInBytes",
 | 
					 | 
				
			||||||
  "6d7fd45329a05fd86b3dbcacde87fe76e33a422d"."profileChangedAt" AS "6d7fd45329a05fd86b3dbcacde87fe76e33a422d_profileChangedAt"
 | 
					 | 
				
			||||||
FROM
 | 
					 | 
				
			||||||
  "shared_links" "SharedLinkEntity"
 | 
					 | 
				
			||||||
  LEFT JOIN "shared_link__asset" "SharedLinkEntity__SharedLinkEntity_assets_SharedLinkEntity" ON "SharedLinkEntity__SharedLinkEntity_assets_SharedLinkEntity"."sharedLinksId" = "SharedLinkEntity"."id"
 | 
					 | 
				
			||||||
  LEFT JOIN "assets" "SharedLinkEntity__SharedLinkEntity_assets" ON "SharedLinkEntity__SharedLinkEntity_assets"."id" = "SharedLinkEntity__SharedLinkEntity_assets_SharedLinkEntity"."assetsId"
 | 
					 | 
				
			||||||
  AND (
 | 
					 | 
				
			||||||
    "SharedLinkEntity__SharedLinkEntity_assets"."deletedAt" IS NULL
 | 
					 | 
				
			||||||
  )
 | 
					  )
 | 
				
			||||||
  LEFT JOIN "albums" "SharedLinkEntity__SharedLinkEntity_album" ON "SharedLinkEntity__SharedLinkEntity_album"."id" = "SharedLinkEntity"."albumId"
 | 
					order by
 | 
				
			||||||
  AND (
 | 
					  "shared_links"."createdAt" desc
 | 
				
			||||||
    "SharedLinkEntity__SharedLinkEntity_album"."deletedAt" IS NULL
 | 
					 | 
				
			||||||
  )
 | 
					 | 
				
			||||||
  LEFT JOIN "users" "6d7fd45329a05fd86b3dbcacde87fe76e33a422d" ON "6d7fd45329a05fd86b3dbcacde87fe76e33a422d"."id" = "SharedLinkEntity__SharedLinkEntity_album"."ownerId"
 | 
					 | 
				
			||||||
  AND (
 | 
					 | 
				
			||||||
    "6d7fd45329a05fd86b3dbcacde87fe76e33a422d"."deletedAt" IS NULL
 | 
					 | 
				
			||||||
  )
 | 
					 | 
				
			||||||
WHERE
 | 
					 | 
				
			||||||
  (("SharedLinkEntity"."userId" = $1))
 | 
					 | 
				
			||||||
ORDER BY
 | 
					 | 
				
			||||||
  "SharedLinkEntity"."createdAt" DESC
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
-- SharedLinkRepository.getByKey
 | 
					-- SharedLinkRepository.getByKey
 | 
				
			||||||
SELECT DISTINCT
 | 
					select
 | 
				
			||||||
  "distinctAlias"."SharedLinkEntity_id" AS "ids_SharedLinkEntity_id"
 | 
					  "shared_links".*,
 | 
				
			||||||
FROM
 | 
					 | 
				
			||||||
  (
 | 
					  (
 | 
				
			||||||
    SELECT
 | 
					    select
 | 
				
			||||||
      "SharedLinkEntity"."id" AS "SharedLinkEntity_id",
 | 
					      to_json(obj)
 | 
				
			||||||
      "SharedLinkEntity"."description" AS "SharedLinkEntity_description",
 | 
					    from
 | 
				
			||||||
      "SharedLinkEntity"."password" AS "SharedLinkEntity_password",
 | 
					      (
 | 
				
			||||||
      "SharedLinkEntity"."userId" AS "SharedLinkEntity_userId",
 | 
					        select
 | 
				
			||||||
      "SharedLinkEntity"."key" AS "SharedLinkEntity_key",
 | 
					          "users"."id",
 | 
				
			||||||
      "SharedLinkEntity"."type" AS "SharedLinkEntity_type",
 | 
					          "users"."email",
 | 
				
			||||||
      "SharedLinkEntity"."createdAt" AS "SharedLinkEntity_createdAt",
 | 
					          "users"."createdAt",
 | 
				
			||||||
      "SharedLinkEntity"."expiresAt" AS "SharedLinkEntity_expiresAt",
 | 
					          "users"."profileImagePath",
 | 
				
			||||||
      "SharedLinkEntity"."allowUpload" AS "SharedLinkEntity_allowUpload",
 | 
					          "users"."isAdmin",
 | 
				
			||||||
      "SharedLinkEntity"."allowDownload" AS "SharedLinkEntity_allowDownload",
 | 
					          "users"."shouldChangePassword",
 | 
				
			||||||
      "SharedLinkEntity"."showExif" AS "SharedLinkEntity_showExif",
 | 
					          "users"."deletedAt",
 | 
				
			||||||
      "SharedLinkEntity"."albumId" AS "SharedLinkEntity_albumId",
 | 
					          "users"."oauthId",
 | 
				
			||||||
      "SharedLinkEntity__SharedLinkEntity_user"."id" AS "SharedLinkEntity__SharedLinkEntity_user_id",
 | 
					          "users"."updatedAt",
 | 
				
			||||||
      "SharedLinkEntity__SharedLinkEntity_user"."name" AS "SharedLinkEntity__SharedLinkEntity_user_name",
 | 
					          "users"."storageLabel",
 | 
				
			||||||
      "SharedLinkEntity__SharedLinkEntity_user"."isAdmin" AS "SharedLinkEntity__SharedLinkEntity_user_isAdmin",
 | 
					          "users"."name",
 | 
				
			||||||
      "SharedLinkEntity__SharedLinkEntity_user"."email" AS "SharedLinkEntity__SharedLinkEntity_user_email",
 | 
					          "users"."quotaSizeInBytes",
 | 
				
			||||||
      "SharedLinkEntity__SharedLinkEntity_user"."storageLabel" AS "SharedLinkEntity__SharedLinkEntity_user_storageLabel",
 | 
					          "users"."quotaUsageInBytes",
 | 
				
			||||||
      "SharedLinkEntity__SharedLinkEntity_user"."oauthId" AS "SharedLinkEntity__SharedLinkEntity_user_oauthId",
 | 
					          "users"."status",
 | 
				
			||||||
      "SharedLinkEntity__SharedLinkEntity_user"."profileImagePath" AS "SharedLinkEntity__SharedLinkEntity_user_profileImagePath",
 | 
					          "users"."profileChangedAt"
 | 
				
			||||||
      "SharedLinkEntity__SharedLinkEntity_user"."shouldChangePassword" AS "SharedLinkEntity__SharedLinkEntity_user_shouldChangePassword",
 | 
					        from
 | 
				
			||||||
      "SharedLinkEntity__SharedLinkEntity_user"."createdAt" AS "SharedLinkEntity__SharedLinkEntity_user_createdAt",
 | 
					          "users"
 | 
				
			||||||
      "SharedLinkEntity__SharedLinkEntity_user"."deletedAt" AS "SharedLinkEntity__SharedLinkEntity_user_deletedAt",
 | 
					        where
 | 
				
			||||||
      "SharedLinkEntity__SharedLinkEntity_user"."status" AS "SharedLinkEntity__SharedLinkEntity_user_status",
 | 
					          "users"."id" = "shared_links"."userId"
 | 
				
			||||||
      "SharedLinkEntity__SharedLinkEntity_user"."updatedAt" AS "SharedLinkEntity__SharedLinkEntity_user_updatedAt",
 | 
					      ) as obj
 | 
				
			||||||
      "SharedLinkEntity__SharedLinkEntity_user"."quotaSizeInBytes" AS "SharedLinkEntity__SharedLinkEntity_user_quotaSizeInBytes",
 | 
					  ) as "user"
 | 
				
			||||||
      "SharedLinkEntity__SharedLinkEntity_user"."quotaUsageInBytes" AS "SharedLinkEntity__SharedLinkEntity_user_quotaUsageInBytes",
 | 
					from
 | 
				
			||||||
      "SharedLinkEntity__SharedLinkEntity_user"."profileChangedAt" AS "SharedLinkEntity__SharedLinkEntity_user_profileChangedAt"
 | 
					  "shared_links"
 | 
				
			||||||
    FROM
 | 
					  left join "albums" on "albums"."id" = "shared_links"."albumId"
 | 
				
			||||||
      "shared_links" "SharedLinkEntity"
 | 
					where
 | 
				
			||||||
      LEFT JOIN "users" "SharedLinkEntity__SharedLinkEntity_user" ON "SharedLinkEntity__SharedLinkEntity_user"."id" = "SharedLinkEntity"."userId"
 | 
					  "shared_links"."key" = $1
 | 
				
			||||||
      AND (
 | 
					  and "albums"."deletedAt" is null
 | 
				
			||||||
        "SharedLinkEntity__SharedLinkEntity_user"."deletedAt" IS NULL
 | 
					  and (
 | 
				
			||||||
      )
 | 
					    "shared_links"."type" = $2
 | 
				
			||||||
    WHERE
 | 
					    or "albums"."id" is not null
 | 
				
			||||||
      (("SharedLinkEntity"."key" = $1))
 | 
					  )
 | 
				
			||||||
  ) "distinctAlias"
 | 
					 | 
				
			||||||
ORDER BY
 | 
					 | 
				
			||||||
  "SharedLinkEntity_id" ASC
 | 
					 | 
				
			||||||
LIMIT
 | 
					 | 
				
			||||||
  1
 | 
					 | 
				
			||||||
 | 
				
			|||||||
@ -1,90 +1,256 @@
 | 
				
			|||||||
import { Injectable } from '@nestjs/common';
 | 
					import { Injectable } from '@nestjs/common';
 | 
				
			||||||
import { InjectRepository } from '@nestjs/typeorm';
 | 
					import { Insertable, Kysely, sql, Updateable } from 'kysely';
 | 
				
			||||||
 | 
					import { jsonObjectFrom } from 'kysely/helpers/postgres';
 | 
				
			||||||
 | 
					import _ from 'lodash';
 | 
				
			||||||
 | 
					import { InjectKysely } from 'nestjs-kysely';
 | 
				
			||||||
 | 
					import { DB, SharedLinks } from 'src/db';
 | 
				
			||||||
import { DummyValue, GenerateSql } from 'src/decorators';
 | 
					import { DummyValue, GenerateSql } from 'src/decorators';
 | 
				
			||||||
import { SharedLinkEntity } from 'src/entities/shared-link.entity';
 | 
					import { SharedLinkEntity } from 'src/entities/shared-link.entity';
 | 
				
			||||||
 | 
					import { SharedLinkType } from 'src/enum';
 | 
				
			||||||
import { ISharedLinkRepository } from 'src/interfaces/shared-link.interface';
 | 
					import { ISharedLinkRepository } from 'src/interfaces/shared-link.interface';
 | 
				
			||||||
import { Repository } from 'typeorm';
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
@Injectable()
 | 
					@Injectable()
 | 
				
			||||||
export class SharedLinkRepository implements ISharedLinkRepository {
 | 
					export class SharedLinkRepository implements ISharedLinkRepository {
 | 
				
			||||||
  constructor(@InjectRepository(SharedLinkEntity) private repository: Repository<SharedLinkEntity>) {}
 | 
					  constructor(@InjectKysely() private db: Kysely<DB>) {}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  @GenerateSql({ params: [DummyValue.UUID, DummyValue.UUID] })
 | 
					  @GenerateSql({ params: [DummyValue.UUID, DummyValue.UUID] })
 | 
				
			||||||
  get(userId: string, id: string): Promise<SharedLinkEntity | null> {
 | 
					  get(userId: string, id: string): Promise<SharedLinkEntity | undefined> {
 | 
				
			||||||
    return this.repository.findOne({
 | 
					    return this.db
 | 
				
			||||||
      where: {
 | 
					      .selectFrom('shared_links')
 | 
				
			||||||
        id,
 | 
					      .selectAll('shared_links')
 | 
				
			||||||
        userId,
 | 
					      .leftJoinLateral(
 | 
				
			||||||
      },
 | 
					        (eb) =>
 | 
				
			||||||
      relations: {
 | 
					          eb
 | 
				
			||||||
        assets: {
 | 
					            .selectFrom('shared_link__asset')
 | 
				
			||||||
          exifInfo: true,
 | 
					            .whereRef('shared_links.id', '=', 'shared_link__asset.sharedLinksId')
 | 
				
			||||||
        },
 | 
					            .innerJoin('assets', 'assets.id', 'shared_link__asset.assetsId')
 | 
				
			||||||
        album: {
 | 
					            .where('assets.deletedAt', 'is', null)
 | 
				
			||||||
          assets: {
 | 
					            .selectAll('assets')
 | 
				
			||||||
            exifInfo: true,
 | 
					            .innerJoinLateral(
 | 
				
			||||||
          },
 | 
					              (eb) => eb.selectFrom('exif').selectAll('exif').whereRef('exif.assetId', '=', 'assets.id').as('exifInfo'),
 | 
				
			||||||
          owner: true,
 | 
					              (join) => join.onTrue(),
 | 
				
			||||||
        },
 | 
					            )
 | 
				
			||||||
      },
 | 
					            .select((eb) => eb.fn.toJson('exifInfo').as('exifInfo'))
 | 
				
			||||||
      order: {
 | 
					            .orderBy('assets.fileCreatedAt', 'asc')
 | 
				
			||||||
        createdAt: 'DESC',
 | 
					            .as('a'),
 | 
				
			||||||
        assets: {
 | 
					        (join) => join.onTrue(),
 | 
				
			||||||
          fileCreatedAt: 'ASC',
 | 
					      )
 | 
				
			||||||
        },
 | 
					      .leftJoinLateral(
 | 
				
			||||||
        album: {
 | 
					        (eb) =>
 | 
				
			||||||
          assets: {
 | 
					          eb
 | 
				
			||||||
            fileCreatedAt: 'ASC',
 | 
					            .selectFrom('albums')
 | 
				
			||||||
          },
 | 
					            .selectAll('albums')
 | 
				
			||||||
        },
 | 
					            .whereRef('albums.id', '=', 'shared_links.albumId')
 | 
				
			||||||
      },
 | 
					            .where('albums.deletedAt', 'is', null)
 | 
				
			||||||
    });
 | 
					            .leftJoin('albums_assets_assets', 'albums_assets_assets.albumsId', 'albums.id')
 | 
				
			||||||
 | 
					            .leftJoinLateral(
 | 
				
			||||||
 | 
					              (eb) =>
 | 
				
			||||||
 | 
					                eb
 | 
				
			||||||
 | 
					                  .selectFrom('assets')
 | 
				
			||||||
 | 
					                  .selectAll('assets')
 | 
				
			||||||
 | 
					                  .whereRef('albums_assets_assets.assetsId', '=', 'assets.id')
 | 
				
			||||||
 | 
					                  .where('assets.deletedAt', 'is', null)
 | 
				
			||||||
 | 
					                  .innerJoinLateral(
 | 
				
			||||||
 | 
					                    (eb) =>
 | 
				
			||||||
 | 
					                      eb
 | 
				
			||||||
 | 
					                        .selectFrom('exif')
 | 
				
			||||||
 | 
					                        .selectAll('exif')
 | 
				
			||||||
 | 
					                        .whereRef('exif.assetId', '=', 'assets.id')
 | 
				
			||||||
 | 
					                        .as('assets_exifInfo'),
 | 
				
			||||||
 | 
					                    (join) => join.onTrue(),
 | 
				
			||||||
 | 
					                  )
 | 
				
			||||||
 | 
					                  .select((eb) => eb.fn.toJson(eb.table('assets_exifInfo')).as('exifInfo'))
 | 
				
			||||||
 | 
					                  .orderBy('assets.fileCreatedAt', 'asc')
 | 
				
			||||||
 | 
					                  .as('assets'),
 | 
				
			||||||
 | 
					              (join) => join.onTrue(),
 | 
				
			||||||
 | 
					            )
 | 
				
			||||||
 | 
					            .innerJoinLateral(
 | 
				
			||||||
 | 
					              (eb) =>
 | 
				
			||||||
 | 
					                eb
 | 
				
			||||||
 | 
					                  .selectFrom('users')
 | 
				
			||||||
 | 
					                  .selectAll('users')
 | 
				
			||||||
 | 
					                  .whereRef('users.id', '=', 'albums.ownerId')
 | 
				
			||||||
 | 
					                  .where('users.deletedAt', 'is', null)
 | 
				
			||||||
 | 
					                  .as('owner'),
 | 
				
			||||||
 | 
					              (join) => join.onTrue(),
 | 
				
			||||||
 | 
					            )
 | 
				
			||||||
 | 
					            .select((eb) =>
 | 
				
			||||||
 | 
					              eb.fn.coalesce(eb.fn.jsonAgg('assets').filterWhere('assets.id', 'is not', null), sql`'[]'`).as('assets'),
 | 
				
			||||||
 | 
					            )
 | 
				
			||||||
 | 
					            .select((eb) => eb.fn.toJson('owner').as('owner'))
 | 
				
			||||||
 | 
					            .groupBy(['albums.id', sql`"owner".*`])
 | 
				
			||||||
 | 
					            .as('album'),
 | 
				
			||||||
 | 
					        (join) => join.onTrue(),
 | 
				
			||||||
 | 
					      )
 | 
				
			||||||
 | 
					      .select((eb) => eb.fn.coalesce(eb.fn.jsonAgg('a').filterWhere('a.id', 'is not', null), sql`'[]'`).as('assets'))
 | 
				
			||||||
 | 
					      .groupBy(['shared_links.id', sql`"album".*`])
 | 
				
			||||||
 | 
					      .select((eb) => eb.fn.toJson('album').as('album'))
 | 
				
			||||||
 | 
					      .where('shared_links.id', '=', id)
 | 
				
			||||||
 | 
					      .where('shared_links.userId', '=', userId)
 | 
				
			||||||
 | 
					      .where((eb) => eb.or([eb('shared_links.type', '=', SharedLinkType.INDIVIDUAL), eb('album.id', 'is not', null)]))
 | 
				
			||||||
 | 
					      .orderBy('shared_links.createdAt', 'desc')
 | 
				
			||||||
 | 
					      .executeTakeFirst() as Promise<SharedLinkEntity | undefined>;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  @GenerateSql({ params: [DummyValue.UUID] })
 | 
					  @GenerateSql({ params: [DummyValue.UUID] })
 | 
				
			||||||
  getAll(userId: string): Promise<SharedLinkEntity[]> {
 | 
					  getAll(userId: string): Promise<SharedLinkEntity[]> {
 | 
				
			||||||
    return this.repository.find({
 | 
					    return this.db
 | 
				
			||||||
      where: {
 | 
					      .selectFrom('shared_links')
 | 
				
			||||||
        userId,
 | 
					      .selectAll('shared_links')
 | 
				
			||||||
      },
 | 
					      .where('shared_links.userId', '=', userId)
 | 
				
			||||||
      relations: {
 | 
					      .leftJoin('shared_link__asset', 'shared_link__asset.sharedLinksId', 'shared_links.id')
 | 
				
			||||||
        assets: true,
 | 
					      .leftJoinLateral(
 | 
				
			||||||
        album: {
 | 
					        (eb) =>
 | 
				
			||||||
          owner: true,
 | 
					          eb
 | 
				
			||||||
        },
 | 
					            .selectFrom('assets')
 | 
				
			||||||
      },
 | 
					            .whereRef('assets.id', '=', 'shared_link__asset.assetsId')
 | 
				
			||||||
      order: {
 | 
					            .where('assets.deletedAt', 'is', null)
 | 
				
			||||||
        createdAt: 'DESC',
 | 
					            .selectAll('assets')
 | 
				
			||||||
      },
 | 
					            .as('assets'),
 | 
				
			||||||
    });
 | 
					        (join) => join.onTrue(),
 | 
				
			||||||
 | 
					      )
 | 
				
			||||||
 | 
					      .leftJoinLateral(
 | 
				
			||||||
 | 
					        (eb) =>
 | 
				
			||||||
 | 
					          eb
 | 
				
			||||||
 | 
					            .selectFrom('albums')
 | 
				
			||||||
 | 
					            .selectAll('albums')
 | 
				
			||||||
 | 
					            .whereRef('albums.id', '=', 'shared_links.albumId')
 | 
				
			||||||
 | 
					            .innerJoinLateral(
 | 
				
			||||||
 | 
					              (eb) =>
 | 
				
			||||||
 | 
					                eb
 | 
				
			||||||
 | 
					                  .selectFrom('users')
 | 
				
			||||||
 | 
					                  .select([
 | 
				
			||||||
 | 
					                    'users.id',
 | 
				
			||||||
 | 
					                    'users.email',
 | 
				
			||||||
 | 
					                    'users.createdAt',
 | 
				
			||||||
 | 
					                    'users.profileImagePath',
 | 
				
			||||||
 | 
					                    'users.isAdmin',
 | 
				
			||||||
 | 
					                    'users.shouldChangePassword',
 | 
				
			||||||
 | 
					                    'users.deletedAt',
 | 
				
			||||||
 | 
					                    'users.oauthId',
 | 
				
			||||||
 | 
					                    'users.updatedAt',
 | 
				
			||||||
 | 
					                    'users.storageLabel',
 | 
				
			||||||
 | 
					                    'users.name',
 | 
				
			||||||
 | 
					                    'users.quotaSizeInBytes',
 | 
				
			||||||
 | 
					                    'users.quotaUsageInBytes',
 | 
				
			||||||
 | 
					                    'users.status',
 | 
				
			||||||
 | 
					                    'users.profileChangedAt',
 | 
				
			||||||
 | 
					                  ])
 | 
				
			||||||
 | 
					                  .whereRef('users.id', '=', 'albums.ownerId')
 | 
				
			||||||
 | 
					                  .where('users.deletedAt', 'is', null)
 | 
				
			||||||
 | 
					                  .as('owner'),
 | 
				
			||||||
 | 
					              (join) => join.onTrue(),
 | 
				
			||||||
 | 
					            )
 | 
				
			||||||
 | 
					            .select((eb) => eb.fn.toJson('owner').as('owner'))
 | 
				
			||||||
 | 
					            .where('albums.deletedAt', 'is', null)
 | 
				
			||||||
 | 
					            .as('album'),
 | 
				
			||||||
 | 
					        (join) => join.onTrue(),
 | 
				
			||||||
 | 
					      )
 | 
				
			||||||
 | 
					      .select((eb) => eb.fn.toJson('album').as('album'))
 | 
				
			||||||
 | 
					      .where((eb) => eb.or([eb('shared_links.type', '=', SharedLinkType.INDIVIDUAL), eb('album.id', 'is not', null)]))
 | 
				
			||||||
 | 
					      .orderBy('shared_links.createdAt', 'desc')
 | 
				
			||||||
 | 
					      .distinctOn(['shared_links.createdAt'])
 | 
				
			||||||
 | 
					      .execute() as unknown as Promise<SharedLinkEntity[]>;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  @GenerateSql({ params: [DummyValue.BUFFER] })
 | 
					  @GenerateSql({ params: [DummyValue.BUFFER] })
 | 
				
			||||||
  async getByKey(key: Buffer): Promise<SharedLinkEntity | null> {
 | 
					  async getByKey(key: Buffer): Promise<SharedLinkEntity | undefined> {
 | 
				
			||||||
    return await this.repository.findOne({
 | 
					    return this.db
 | 
				
			||||||
      where: {
 | 
					      .selectFrom('shared_links')
 | 
				
			||||||
        key,
 | 
					      .selectAll('shared_links')
 | 
				
			||||||
      },
 | 
					      .where('shared_links.key', '=', key)
 | 
				
			||||||
      relations: {
 | 
					      .leftJoin('albums', 'albums.id', 'shared_links.albumId')
 | 
				
			||||||
        user: true,
 | 
					      .where('albums.deletedAt', 'is', null)
 | 
				
			||||||
      },
 | 
					      .select((eb) =>
 | 
				
			||||||
    });
 | 
					        jsonObjectFrom(
 | 
				
			||||||
 | 
					          eb
 | 
				
			||||||
 | 
					            .selectFrom('users')
 | 
				
			||||||
 | 
					            .select([
 | 
				
			||||||
 | 
					              'users.id',
 | 
				
			||||||
 | 
					              'users.email',
 | 
				
			||||||
 | 
					              'users.createdAt',
 | 
				
			||||||
 | 
					              'users.profileImagePath',
 | 
				
			||||||
 | 
					              'users.isAdmin',
 | 
				
			||||||
 | 
					              'users.shouldChangePassword',
 | 
				
			||||||
 | 
					              'users.deletedAt',
 | 
				
			||||||
 | 
					              'users.oauthId',
 | 
				
			||||||
 | 
					              'users.updatedAt',
 | 
				
			||||||
 | 
					              'users.storageLabel',
 | 
				
			||||||
 | 
					              'users.name',
 | 
				
			||||||
 | 
					              'users.quotaSizeInBytes',
 | 
				
			||||||
 | 
					              'users.quotaUsageInBytes',
 | 
				
			||||||
 | 
					              'users.status',
 | 
				
			||||||
 | 
					              'users.profileChangedAt',
 | 
				
			||||||
 | 
					            ])
 | 
				
			||||||
 | 
					            .whereRef('users.id', '=', 'shared_links.userId'),
 | 
				
			||||||
 | 
					        ).as('user'),
 | 
				
			||||||
 | 
					      )
 | 
				
			||||||
 | 
					      .where((eb) => eb.or([eb('shared_links.type', '=', SharedLinkType.INDIVIDUAL), eb('albums.id', 'is not', null)]))
 | 
				
			||||||
 | 
					      .executeTakeFirst() as Promise<SharedLinkEntity | undefined>;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  create(entity: Partial<SharedLinkEntity>): Promise<SharedLinkEntity> {
 | 
					  async create(entity: Insertable<SharedLinks> & { assetIds?: string[] }): Promise<SharedLinkEntity> {
 | 
				
			||||||
    return this.save(entity);
 | 
					    const { id } = await this.db
 | 
				
			||||||
 | 
					      .insertInto('shared_links')
 | 
				
			||||||
 | 
					      .values(_.omit(entity, 'assetIds'))
 | 
				
			||||||
 | 
					      .returningAll()
 | 
				
			||||||
 | 
					      .executeTakeFirstOrThrow();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (entity.assetIds && entity.assetIds.length > 0) {
 | 
				
			||||||
 | 
					      await this.db
 | 
				
			||||||
 | 
					        .insertInto('shared_link__asset')
 | 
				
			||||||
 | 
					        .values(entity.assetIds!.map((assetsId) => ({ assetsId, sharedLinksId: id })))
 | 
				
			||||||
 | 
					        .execute();
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return this.getSharedLinks(id);
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  update(entity: Partial<SharedLinkEntity>): Promise<SharedLinkEntity> {
 | 
					  async update(entity: Updateable<SharedLinks> & { id: string; assetIds?: string[] }): Promise<SharedLinkEntity> {
 | 
				
			||||||
    return this.save(entity);
 | 
					    const { id } = await this.db
 | 
				
			||||||
 | 
					      .updateTable('shared_links')
 | 
				
			||||||
 | 
					      .set(_.omit(entity, 'assets', 'album', 'assetIds'))
 | 
				
			||||||
 | 
					      .where('shared_links.id', '=', entity.id)
 | 
				
			||||||
 | 
					      .returningAll()
 | 
				
			||||||
 | 
					      .executeTakeFirstOrThrow();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (entity.assetIds && entity.assetIds.length > 0) {
 | 
				
			||||||
 | 
					      await this.db
 | 
				
			||||||
 | 
					        .insertInto('shared_link__asset')
 | 
				
			||||||
 | 
					        .values(entity.assetIds!.map((assetsId) => ({ assetsId, sharedLinksId: id })))
 | 
				
			||||||
 | 
					        .execute();
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return this.getSharedLinks(id);
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  async remove(entity: SharedLinkEntity): Promise<void> {
 | 
					  async remove(entity: SharedLinkEntity): Promise<void> {
 | 
				
			||||||
    await this.repository.remove(entity);
 | 
					    await this.db.deleteFrom('shared_links').where('shared_links.id', '=', entity.id).execute();
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  private async save(entity: Partial<SharedLinkEntity>): Promise<SharedLinkEntity> {
 | 
					  private getSharedLinks(id: string) {
 | 
				
			||||||
    await this.repository.save(entity);
 | 
					    return this.db
 | 
				
			||||||
    return this.repository.findOneOrFail({ where: { id: entity.id } });
 | 
					      .selectFrom('shared_links')
 | 
				
			||||||
 | 
					      .selectAll('shared_links')
 | 
				
			||||||
 | 
					      .where('shared_links.id', '=', id)
 | 
				
			||||||
 | 
					      .leftJoin('shared_link__asset', 'shared_link__asset.sharedLinksId', 'shared_links.id')
 | 
				
			||||||
 | 
					      .leftJoinLateral(
 | 
				
			||||||
 | 
					        (eb) =>
 | 
				
			||||||
 | 
					          eb
 | 
				
			||||||
 | 
					            .selectFrom('assets')
 | 
				
			||||||
 | 
					            .whereRef('assets.id', '=', 'shared_link__asset.assetsId')
 | 
				
			||||||
 | 
					            .selectAll('assets')
 | 
				
			||||||
 | 
					            .innerJoinLateral(
 | 
				
			||||||
 | 
					              (eb) => eb.selectFrom('exif').whereRef('exif.assetId', '=', 'assets.id').selectAll().as('exif'),
 | 
				
			||||||
 | 
					              (join) => join.onTrue(),
 | 
				
			||||||
 | 
					            )
 | 
				
			||||||
 | 
					            .as('assets'),
 | 
				
			||||||
 | 
					        (join) => join.onTrue(),
 | 
				
			||||||
 | 
					      )
 | 
				
			||||||
 | 
					      .select((eb) =>
 | 
				
			||||||
 | 
					        eb.fn.coalesce(eb.fn.jsonAgg('assets').filterWhere('assets.id', 'is not', null), sql`'[]'`).as('assets'),
 | 
				
			||||||
 | 
					      )
 | 
				
			||||||
 | 
					      .groupBy('shared_links.id')
 | 
				
			||||||
 | 
					      .executeTakeFirstOrThrow() as Promise<SharedLinkEntity>;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -275,7 +275,6 @@ describe('AuthService', () => {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
  describe('validate - shared key', () => {
 | 
					  describe('validate - shared key', () => {
 | 
				
			||||||
    it('should not accept a non-existent key', async () => {
 | 
					    it('should not accept a non-existent key', async () => {
 | 
				
			||||||
      sharedLinkMock.getByKey.mockResolvedValue(null);
 | 
					 | 
				
			||||||
      await expect(
 | 
					      await expect(
 | 
				
			||||||
        sut.authenticate({
 | 
					        sut.authenticate({
 | 
				
			||||||
          headers: { 'x-immich-share-key': 'key' },
 | 
					          headers: { 'x-immich-share-key': 'key' },
 | 
				
			||||||
 | 
				
			|||||||
@ -76,7 +76,6 @@ describe(SharedLinkService.name, () => {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
  describe('get', () => {
 | 
					  describe('get', () => {
 | 
				
			||||||
    it('should throw an error for an invalid shared link', async () => {
 | 
					    it('should throw an error for an invalid shared link', async () => {
 | 
				
			||||||
      sharedLinkMock.get.mockResolvedValue(null);
 | 
					 | 
				
			||||||
      await expect(sut.get(authStub.user1, 'missing-id')).rejects.toBeInstanceOf(BadRequestException);
 | 
					      await expect(sut.get(authStub.user1, 'missing-id')).rejects.toBeInstanceOf(BadRequestException);
 | 
				
			||||||
      expect(sharedLinkMock.get).toHaveBeenCalledWith(authStub.user1.user.id, 'missing-id');
 | 
					      expect(sharedLinkMock.get).toHaveBeenCalledWith(authStub.user1.user.id, 'missing-id');
 | 
				
			||||||
      expect(sharedLinkMock.update).not.toHaveBeenCalled();
 | 
					      expect(sharedLinkMock.update).not.toHaveBeenCalled();
 | 
				
			||||||
@ -130,7 +129,6 @@ describe(SharedLinkService.name, () => {
 | 
				
			|||||||
        albumId: albumStub.oneAsset.id,
 | 
					        albumId: albumStub.oneAsset.id,
 | 
				
			||||||
        allowDownload: true,
 | 
					        allowDownload: true,
 | 
				
			||||||
        allowUpload: true,
 | 
					        allowUpload: true,
 | 
				
			||||||
        assets: [],
 | 
					 | 
				
			||||||
        description: null,
 | 
					        description: null,
 | 
				
			||||||
        expiresAt: null,
 | 
					        expiresAt: null,
 | 
				
			||||||
        showExif: true,
 | 
					        showExif: true,
 | 
				
			||||||
@ -160,7 +158,7 @@ describe(SharedLinkService.name, () => {
 | 
				
			|||||||
        albumId: null,
 | 
					        albumId: null,
 | 
				
			||||||
        allowDownload: true,
 | 
					        allowDownload: true,
 | 
				
			||||||
        allowUpload: true,
 | 
					        allowUpload: true,
 | 
				
			||||||
        assets: [{ id: assetStub.image.id }],
 | 
					        assetIds: [assetStub.image.id],
 | 
				
			||||||
        description: null,
 | 
					        description: null,
 | 
				
			||||||
        expiresAt: null,
 | 
					        expiresAt: null,
 | 
				
			||||||
        showExif: true,
 | 
					        showExif: true,
 | 
				
			||||||
@ -190,7 +188,7 @@ describe(SharedLinkService.name, () => {
 | 
				
			|||||||
        albumId: null,
 | 
					        albumId: null,
 | 
				
			||||||
        allowDownload: false,
 | 
					        allowDownload: false,
 | 
				
			||||||
        allowUpload: true,
 | 
					        allowUpload: true,
 | 
				
			||||||
        assets: [{ id: assetStub.image.id }],
 | 
					        assetIds: [assetStub.image.id],
 | 
				
			||||||
        description: null,
 | 
					        description: null,
 | 
				
			||||||
        expiresAt: null,
 | 
					        expiresAt: null,
 | 
				
			||||||
        showExif: false,
 | 
					        showExif: false,
 | 
				
			||||||
@ -201,7 +199,6 @@ describe(SharedLinkService.name, () => {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
  describe('update', () => {
 | 
					  describe('update', () => {
 | 
				
			||||||
    it('should throw an error for an invalid shared link', async () => {
 | 
					    it('should throw an error for an invalid shared link', async () => {
 | 
				
			||||||
      sharedLinkMock.get.mockResolvedValue(null);
 | 
					 | 
				
			||||||
      await expect(sut.update(authStub.user1, 'missing-id', {})).rejects.toBeInstanceOf(BadRequestException);
 | 
					      await expect(sut.update(authStub.user1, 'missing-id', {})).rejects.toBeInstanceOf(BadRequestException);
 | 
				
			||||||
      expect(sharedLinkMock.get).toHaveBeenCalledWith(authStub.user1.user.id, 'missing-id');
 | 
					      expect(sharedLinkMock.get).toHaveBeenCalledWith(authStub.user1.user.id, 'missing-id');
 | 
				
			||||||
      expect(sharedLinkMock.update).not.toHaveBeenCalled();
 | 
					      expect(sharedLinkMock.update).not.toHaveBeenCalled();
 | 
				
			||||||
@ -222,7 +219,6 @@ describe(SharedLinkService.name, () => {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
  describe('remove', () => {
 | 
					  describe('remove', () => {
 | 
				
			||||||
    it('should throw an error for an invalid shared link', async () => {
 | 
					    it('should throw an error for an invalid shared link', async () => {
 | 
				
			||||||
      sharedLinkMock.get.mockResolvedValue(null);
 | 
					 | 
				
			||||||
      await expect(sut.remove(authStub.user1, 'missing-id')).rejects.toBeInstanceOf(BadRequestException);
 | 
					      await expect(sut.remove(authStub.user1, 'missing-id')).rejects.toBeInstanceOf(BadRequestException);
 | 
				
			||||||
      expect(sharedLinkMock.get).toHaveBeenCalledWith(authStub.user1.user.id, 'missing-id');
 | 
					      expect(sharedLinkMock.get).toHaveBeenCalledWith(authStub.user1.user.id, 'missing-id');
 | 
				
			||||||
      expect(sharedLinkMock.update).not.toHaveBeenCalled();
 | 
					      expect(sharedLinkMock.update).not.toHaveBeenCalled();
 | 
				
			||||||
@ -258,9 +254,10 @@ describe(SharedLinkService.name, () => {
 | 
				
			|||||||
      ]);
 | 
					      ]);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      expect(accessMock.asset.checkOwnerAccess).toHaveBeenCalledTimes(1);
 | 
					      expect(accessMock.asset.checkOwnerAccess).toHaveBeenCalledTimes(1);
 | 
				
			||||||
 | 
					      expect(sharedLinkMock.update).toHaveBeenCalled();
 | 
				
			||||||
      expect(sharedLinkMock.update).toHaveBeenCalledWith({
 | 
					      expect(sharedLinkMock.update).toHaveBeenCalledWith({
 | 
				
			||||||
        ...sharedLinkStub.individual,
 | 
					        ...sharedLinkStub.individual,
 | 
				
			||||||
        assets: [assetStub.image, { id: 'asset-3' }],
 | 
					        assetIds: ['asset-3'],
 | 
				
			||||||
      });
 | 
					      });
 | 
				
			||||||
    });
 | 
					    });
 | 
				
			||||||
  });
 | 
					  });
 | 
				
			||||||
 | 
				
			|||||||
@ -10,7 +10,6 @@ import {
 | 
				
			|||||||
  SharedLinkPasswordDto,
 | 
					  SharedLinkPasswordDto,
 | 
				
			||||||
  SharedLinkResponseDto,
 | 
					  SharedLinkResponseDto,
 | 
				
			||||||
} from 'src/dtos/shared-link.dto';
 | 
					} from 'src/dtos/shared-link.dto';
 | 
				
			||||||
import { AssetEntity } from 'src/entities/asset.entity';
 | 
					 | 
				
			||||||
import { SharedLinkEntity } from 'src/entities/shared-link.entity';
 | 
					import { SharedLinkEntity } from 'src/entities/shared-link.entity';
 | 
				
			||||||
import { Permission, SharedLinkType } from 'src/enum';
 | 
					import { Permission, SharedLinkType } from 'src/enum';
 | 
				
			||||||
import { BaseService } from 'src/services/base.service';
 | 
					import { BaseService } from 'src/services/base.service';
 | 
				
			||||||
@ -67,7 +66,7 @@ export class SharedLinkService extends BaseService {
 | 
				
			|||||||
      userId: auth.user.id,
 | 
					      userId: auth.user.id,
 | 
				
			||||||
      type: dto.type,
 | 
					      type: dto.type,
 | 
				
			||||||
      albumId: dto.albumId || null,
 | 
					      albumId: dto.albumId || null,
 | 
				
			||||||
      assets: (dto.assetIds || []).map((id) => ({ id }) as AssetEntity),
 | 
					      assetIds: dto.assetIds,
 | 
				
			||||||
      description: dto.description || null,
 | 
					      description: dto.description || null,
 | 
				
			||||||
      password: dto.password,
 | 
					      password: dto.password,
 | 
				
			||||||
      expiresAt: dto.expiresAt || null,
 | 
					      expiresAt: dto.expiresAt || null,
 | 
				
			||||||
@ -138,10 +137,12 @@ export class SharedLinkService extends BaseService {
 | 
				
			|||||||
      }
 | 
					      }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      results.push({ assetId, success: true });
 | 
					      results.push({ assetId, success: true });
 | 
				
			||||||
      sharedLink.assets.push({ id: assetId } as AssetEntity);
 | 
					 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    await this.sharedLinkRepository.update(sharedLink);
 | 
					    await this.sharedLinkRepository.update({
 | 
				
			||||||
 | 
					      ...sharedLink,
 | 
				
			||||||
 | 
					      assetIds: results.filter(({ success }) => success).map(({ assetId }) => assetId),
 | 
				
			||||||
 | 
					    });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    return results;
 | 
					    return results;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user