mirror of
https://github.com/immich-app/immich.git
synced 2025-11-10 00:33:17 -05:00
Merge branch 'main' into rknn-toolkit-lite2
This commit is contained in:
commit
59e4b6598e
11
cli/package-lock.json
generated
11
cli/package-lock.json
generated
@ -32,7 +32,7 @@
|
|||||||
"cli-progress": "^3.12.0",
|
"cli-progress": "^3.12.0",
|
||||||
"commander": "^12.0.0",
|
"commander": "^12.0.0",
|
||||||
"eslint": "^9.14.0",
|
"eslint": "^9.14.0",
|
||||||
"eslint-config-prettier": "^9.1.0",
|
"eslint-config-prettier": "^10.0.0",
|
||||||
"eslint-plugin-prettier": "^5.1.3",
|
"eslint-plugin-prettier": "^5.1.3",
|
||||||
"eslint-plugin-unicorn": "^56.0.1",
|
"eslint-plugin-unicorn": "^56.0.1",
|
||||||
"globals": "^15.9.0",
|
"globals": "^15.9.0",
|
||||||
@ -2317,12 +2317,13 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/eslint-config-prettier": {
|
"node_modules/eslint-config-prettier": {
|
||||||
"version": "9.1.0",
|
"version": "10.0.1",
|
||||||
"resolved": "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-9.1.0.tgz",
|
"resolved": "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-10.0.1.tgz",
|
||||||
"integrity": "sha512-NSWl5BFQWEPi1j4TjVNItzYV7dZXZ+wP6I6ZhrBGpChQhZRUaElihE9uRRkcbRnNb76UMKDF3r+WTmNcGPKsqw==",
|
"integrity": "sha512-lZBts941cyJyeaooiKxAtzoPHTN+GbQTJFAIdQbRhA4/8whaAraEh47Whw/ZFfrjNSnlAxqfm9i0XVAEkULjCw==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
"bin": {
|
"bin": {
|
||||||
"eslint-config-prettier": "bin/cli.js"
|
"eslint-config-prettier": "build/bin/cli.js"
|
||||||
},
|
},
|
||||||
"peerDependencies": {
|
"peerDependencies": {
|
||||||
"eslint": ">=7.0.0"
|
"eslint": ">=7.0.0"
|
||||||
|
|||||||
@ -28,7 +28,7 @@
|
|||||||
"cli-progress": "^3.12.0",
|
"cli-progress": "^3.12.0",
|
||||||
"commander": "^12.0.0",
|
"commander": "^12.0.0",
|
||||||
"eslint": "^9.14.0",
|
"eslint": "^9.14.0",
|
||||||
"eslint-config-prettier": "^9.1.0",
|
"eslint-config-prettier": "^10.0.0",
|
||||||
"eslint-plugin-prettier": "^5.1.3",
|
"eslint-plugin-prettier": "^5.1.3",
|
||||||
"eslint-plugin-unicorn": "^56.0.1",
|
"eslint-plugin-unicorn": "^56.0.1",
|
||||||
"globals": "^15.9.0",
|
"globals": "^15.9.0",
|
||||||
|
|||||||
@ -111,7 +111,7 @@ alt="Go to Docker Tab and visit the address listed next to immich-web"
|
|||||||
|
|
||||||
<details >
|
<details >
|
||||||
<summary>Using the FolderView plugin for organizing your Docker containers? Click me! Otherwise you're complete!</summary>
|
<summary>Using the FolderView plugin for organizing your Docker containers? Click me! Otherwise you're complete!</summary>
|
||||||
<p>If you are using the FolderView plugin go the Docker tab and select "<b>New Folder</b>".<br />Label it <i>"Immich"</i> and use this URL as the logo: https://raw.githubusercontent.com/immich-app/immich/main/design/immich-logo.webp<br/>Then simply select all the Immich related containers before clicking "<b>Submit</b>"</p>
|
<p>If you are using the FolderView plugin go the Docker tab and select "<b>New Folder</b>".<br />Label it <i>"Immich"</i> and use this URL as the logo: https://raw.githubusercontent.com/immich-app/immich/main/design/immich-logo.png<br/>Then simply select all the Immich related containers before clicking "<b>Submit</b>"</p>
|
||||||
<img
|
<img
|
||||||
src={require('./img/unraid07.webp').default}
|
src={require('./img/unraid07.webp').default}
|
||||||
width="80%"
|
width="80%"
|
||||||
|
|||||||
13
e2e/package-lock.json
generated
13
e2e/package-lock.json
generated
@ -24,7 +24,7 @@
|
|||||||
"@typescript-eslint/parser": "^8.15.0",
|
"@typescript-eslint/parser": "^8.15.0",
|
||||||
"@vitest/coverage-v8": "^2.0.5",
|
"@vitest/coverage-v8": "^2.0.5",
|
||||||
"eslint": "^9.14.0",
|
"eslint": "^9.14.0",
|
||||||
"eslint-config-prettier": "^9.1.0",
|
"eslint-config-prettier": "^10.0.0",
|
||||||
"eslint-plugin-prettier": "^5.1.3",
|
"eslint-plugin-prettier": "^5.1.3",
|
||||||
"eslint-plugin-unicorn": "^56.0.1",
|
"eslint-plugin-unicorn": "^56.0.1",
|
||||||
"exiftool-vendored": "^28.3.1",
|
"exiftool-vendored": "^28.3.1",
|
||||||
@ -72,7 +72,7 @@
|
|||||||
"cli-progress": "^3.12.0",
|
"cli-progress": "^3.12.0",
|
||||||
"commander": "^12.0.0",
|
"commander": "^12.0.0",
|
||||||
"eslint": "^9.14.0",
|
"eslint": "^9.14.0",
|
||||||
"eslint-config-prettier": "^9.1.0",
|
"eslint-config-prettier": "^10.0.0",
|
||||||
"eslint-plugin-prettier": "^5.1.3",
|
"eslint-plugin-prettier": "^5.1.3",
|
||||||
"eslint-plugin-unicorn": "^56.0.1",
|
"eslint-plugin-unicorn": "^56.0.1",
|
||||||
"globals": "^15.9.0",
|
"globals": "^15.9.0",
|
||||||
@ -3156,12 +3156,13 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/eslint-config-prettier": {
|
"node_modules/eslint-config-prettier": {
|
||||||
"version": "9.1.0",
|
"version": "10.0.1",
|
||||||
"resolved": "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-9.1.0.tgz",
|
"resolved": "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-10.0.1.tgz",
|
||||||
"integrity": "sha512-NSWl5BFQWEPi1j4TjVNItzYV7dZXZ+wP6I6ZhrBGpChQhZRUaElihE9uRRkcbRnNb76UMKDF3r+WTmNcGPKsqw==",
|
"integrity": "sha512-lZBts941cyJyeaooiKxAtzoPHTN+GbQTJFAIdQbRhA4/8whaAraEh47Whw/ZFfrjNSnlAxqfm9i0XVAEkULjCw==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
"bin": {
|
"bin": {
|
||||||
"eslint-config-prettier": "bin/cli.js"
|
"eslint-config-prettier": "build/bin/cli.js"
|
||||||
},
|
},
|
||||||
"peerDependencies": {
|
"peerDependencies": {
|
||||||
"eslint": ">=7.0.0"
|
"eslint": ">=7.0.0"
|
||||||
|
|||||||
@ -34,7 +34,7 @@
|
|||||||
"@typescript-eslint/parser": "^8.15.0",
|
"@typescript-eslint/parser": "^8.15.0",
|
||||||
"@vitest/coverage-v8": "^2.0.5",
|
"@vitest/coverage-v8": "^2.0.5",
|
||||||
"eslint": "^9.14.0",
|
"eslint": "^9.14.0",
|
||||||
"eslint-config-prettier": "^9.1.0",
|
"eslint-config-prettier": "^10.0.0",
|
||||||
"eslint-plugin-prettier": "^5.1.3",
|
"eslint-plugin-prettier": "^5.1.3",
|
||||||
"eslint-plugin-unicorn": "^56.0.1",
|
"eslint-plugin-unicorn": "^56.0.1",
|
||||||
"exiftool-vendored": "^28.3.1",
|
"exiftool-vendored": "^28.3.1",
|
||||||
|
|||||||
@ -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,4 +1,6 @@
|
|||||||
{
|
{
|
||||||
|
"start_date": "Start date",
|
||||||
|
"end_date": "End date",
|
||||||
"action_common_back": "Back",
|
"action_common_back": "Back",
|
||||||
"action_common_cancel": "Cancel",
|
"action_common_cancel": "Cancel",
|
||||||
"action_common_clear": "Clear",
|
"action_common_clear": "Clear",
|
||||||
|
|||||||
@ -275,7 +275,9 @@ class SearchPage extends HookConsumerWidget {
|
|||||||
errorInvalidText: 'invalid_date'.tr(),
|
errorInvalidText: 'invalid_date'.tr(),
|
||||||
fieldStartHintText: 'start_date'.tr(),
|
fieldStartHintText: 'start_date'.tr(),
|
||||||
fieldEndHintText: 'end_date'.tr(),
|
fieldEndHintText: 'end_date'.tr(),
|
||||||
initialEntryMode: DatePickerEntryMode.input,
|
initialEntryMode: DatePickerEntryMode.calendar,
|
||||||
|
keyboardType: TextInputType.text,
|
||||||
|
locale: context.locale,
|
||||||
);
|
);
|
||||||
|
|
||||||
if (date == null) {
|
if (date == null) {
|
||||||
|
|||||||
10
server/package-lock.json
generated
10
server/package-lock.json
generated
@ -98,7 +98,7 @@
|
|||||||
"@typescript-eslint/parser": "^8.15.0",
|
"@typescript-eslint/parser": "^8.15.0",
|
||||||
"@vitest/coverage-v8": "^2.0.5",
|
"@vitest/coverage-v8": "^2.0.5",
|
||||||
"eslint": "^9.14.0",
|
"eslint": "^9.14.0",
|
||||||
"eslint-config-prettier": "^9.1.0",
|
"eslint-config-prettier": "^10.0.0",
|
||||||
"eslint-plugin-prettier": "^5.1.3",
|
"eslint-plugin-prettier": "^5.1.3",
|
||||||
"eslint-plugin-unicorn": "^56.0.1",
|
"eslint-plugin-unicorn": "^56.0.1",
|
||||||
"globals": "^15.9.0",
|
"globals": "^15.9.0",
|
||||||
@ -8183,13 +8183,13 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/eslint-config-prettier": {
|
"node_modules/eslint-config-prettier": {
|
||||||
"version": "9.1.0",
|
"version": "10.0.1",
|
||||||
"resolved": "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-9.1.0.tgz",
|
"resolved": "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-10.0.1.tgz",
|
||||||
"integrity": "sha512-NSWl5BFQWEPi1j4TjVNItzYV7dZXZ+wP6I6ZhrBGpChQhZRUaElihE9uRRkcbRnNb76UMKDF3r+WTmNcGPKsqw==",
|
"integrity": "sha512-lZBts941cyJyeaooiKxAtzoPHTN+GbQTJFAIdQbRhA4/8whaAraEh47Whw/ZFfrjNSnlAxqfm9i0XVAEkULjCw==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"bin": {
|
"bin": {
|
||||||
"eslint-config-prettier": "bin/cli.js"
|
"eslint-config-prettier": "build/bin/cli.js"
|
||||||
},
|
},
|
||||||
"peerDependencies": {
|
"peerDependencies": {
|
||||||
"eslint": ">=7.0.0"
|
"eslint": ">=7.0.0"
|
||||||
|
|||||||
@ -124,7 +124,7 @@
|
|||||||
"@typescript-eslint/parser": "^8.15.0",
|
"@typescript-eslint/parser": "^8.15.0",
|
||||||
"@vitest/coverage-v8": "^2.0.5",
|
"@vitest/coverage-v8": "^2.0.5",
|
||||||
"eslint": "^9.14.0",
|
"eslint": "^9.14.0",
|
||||||
"eslint-config-prettier": "^9.1.0",
|
"eslint-config-prettier": "^10.0.0",
|
||||||
"eslint-plugin-prettier": "^5.1.3",
|
"eslint-plugin-prettier": "^5.1.3",
|
||||||
"eslint-plugin-unicorn": "^56.0.1",
|
"eslint-plugin-unicorn": "^56.0.1",
|
||||||
"globals": "^15.9.0",
|
"globals": "^15.9.0",
|
||||||
|
|||||||
@ -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;
|
||||||
}
|
}
|
||||||
|
|||||||
10
web/package-lock.json
generated
10
web/package-lock.json
generated
@ -53,7 +53,7 @@
|
|||||||
"autoprefixer": "^10.4.17",
|
"autoprefixer": "^10.4.17",
|
||||||
"dotenv": "^16.4.7",
|
"dotenv": "^16.4.7",
|
||||||
"eslint": "^9.18.0",
|
"eslint": "^9.18.0",
|
||||||
"eslint-config-prettier": "^9.1.0",
|
"eslint-config-prettier": "^10.0.0",
|
||||||
"eslint-plugin-svelte": "^2.46.1",
|
"eslint-plugin-svelte": "^2.46.1",
|
||||||
"eslint-plugin-unicorn": "^56.0.1",
|
"eslint-plugin-unicorn": "^56.0.1",
|
||||||
"factory.ts": "^1.4.1",
|
"factory.ts": "^1.4.1",
|
||||||
@ -3926,13 +3926,13 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/eslint-config-prettier": {
|
"node_modules/eslint-config-prettier": {
|
||||||
"version": "9.1.0",
|
"version": "10.0.1",
|
||||||
"resolved": "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-9.1.0.tgz",
|
"resolved": "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-10.0.1.tgz",
|
||||||
"integrity": "sha512-NSWl5BFQWEPi1j4TjVNItzYV7dZXZ+wP6I6ZhrBGpChQhZRUaElihE9uRRkcbRnNb76UMKDF3r+WTmNcGPKsqw==",
|
"integrity": "sha512-lZBts941cyJyeaooiKxAtzoPHTN+GbQTJFAIdQbRhA4/8whaAraEh47Whw/ZFfrjNSnlAxqfm9i0XVAEkULjCw==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"bin": {
|
"bin": {
|
||||||
"eslint-config-prettier": "bin/cli.js"
|
"eslint-config-prettier": "build/bin/cli.js"
|
||||||
},
|
},
|
||||||
"peerDependencies": {
|
"peerDependencies": {
|
||||||
"eslint": ">=7.0.0"
|
"eslint": ">=7.0.0"
|
||||||
|
|||||||
@ -44,7 +44,7 @@
|
|||||||
"autoprefixer": "^10.4.17",
|
"autoprefixer": "^10.4.17",
|
||||||
"dotenv": "^16.4.7",
|
"dotenv": "^16.4.7",
|
||||||
"eslint": "^9.18.0",
|
"eslint": "^9.18.0",
|
||||||
"eslint-config-prettier": "^9.1.0",
|
"eslint-config-prettier": "^10.0.0",
|
||||||
"eslint-plugin-svelte": "^2.46.1",
|
"eslint-plugin-svelte": "^2.46.1",
|
||||||
"eslint-plugin-unicorn": "^56.0.1",
|
"eslint-plugin-unicorn": "^56.0.1",
|
||||||
"factory.ts": "^1.4.1",
|
"factory.ts": "^1.4.1",
|
||||||
|
|||||||
@ -40,7 +40,7 @@
|
|||||||
<section
|
<section
|
||||||
id="memory-lane"
|
id="memory-lane"
|
||||||
bind:this={memoryLaneElement}
|
bind:this={memoryLaneElement}
|
||||||
class="relative mt-5 overflow-x-hidden whitespace-nowrap transition-all"
|
class="relative mt-5 overflow-hidden whitespace-nowrap transition-all"
|
||||||
use:resizeObserver={({ width }) => (offsetWidth = width)}
|
use:resizeObserver={({ width }) => (offsetWidth = width)}
|
||||||
onscroll={onScroll}
|
onscroll={onScroll}
|
||||||
>
|
>
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user