mirror of
https://github.com/immich-app/immich.git
synced 2026-06-16 20:02:15 -07:00
Compare commits
2 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| ba3e0560ed | |||
| 42782bf842 |
@@ -16508,9 +16508,7 @@
|
||||
},
|
||||
"albumThumbnailAssetId": {
|
||||
"description": "Thumbnail asset ID",
|
||||
"format": "uuid",
|
||||
"nullable": true,
|
||||
"pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-4[0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12})$",
|
||||
"type": "string"
|
||||
},
|
||||
"albumUsers": {
|
||||
@@ -16553,8 +16551,6 @@
|
||||
},
|
||||
"id": {
|
||||
"description": "Album ID",
|
||||
"format": "uuid",
|
||||
"pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-4[0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12})$",
|
||||
"type": "string"
|
||||
},
|
||||
"isActivityEnabled": {
|
||||
@@ -16797,8 +16793,6 @@
|
||||
},
|
||||
"id": {
|
||||
"description": "API key ID",
|
||||
"format": "uuid",
|
||||
"pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-4[0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12})$",
|
||||
"type": "string"
|
||||
},
|
||||
"name": {
|
||||
@@ -17007,8 +17001,6 @@
|
||||
},
|
||||
"id": {
|
||||
"description": "Asset ID",
|
||||
"format": "uuid",
|
||||
"pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-4[0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12})$",
|
||||
"type": "string"
|
||||
},
|
||||
"isTrashed": {
|
||||
@@ -17387,8 +17379,6 @@
|
||||
"properties": {
|
||||
"assetId": {
|
||||
"description": "Asset ID",
|
||||
"format": "uuid",
|
||||
"pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-4[0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12})$",
|
||||
"type": "string"
|
||||
},
|
||||
"error": {
|
||||
@@ -17504,8 +17494,6 @@
|
||||
"properties": {
|
||||
"id": {
|
||||
"description": "Asset media ID",
|
||||
"format": "uuid",
|
||||
"pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-4[0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12})$",
|
||||
"type": "string"
|
||||
},
|
||||
"status": {
|
||||
@@ -17574,8 +17562,6 @@
|
||||
"properties": {
|
||||
"assetId": {
|
||||
"description": "Asset ID",
|
||||
"format": "uuid",
|
||||
"pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-4[0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12})$",
|
||||
"type": "string"
|
||||
},
|
||||
"key": {
|
||||
@@ -17823,9 +17809,7 @@
|
||||
},
|
||||
"duplicateId": {
|
||||
"description": "Duplicate group ID",
|
||||
"format": "uuid",
|
||||
"nullable": true,
|
||||
"pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-4[0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12})$",
|
||||
"type": "string"
|
||||
},
|
||||
"duration": {
|
||||
@@ -17861,8 +17845,6 @@
|
||||
},
|
||||
"id": {
|
||||
"description": "Asset ID",
|
||||
"format": "uuid",
|
||||
"pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-4[0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12})$",
|
||||
"type": "string"
|
||||
},
|
||||
"isArchived": {
|
||||
@@ -17941,8 +17923,6 @@
|
||||
},
|
||||
"ownerId": {
|
||||
"description": "Owner user ID",
|
||||
"format": "uuid",
|
||||
"pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-4[0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12})$",
|
||||
"type": "string"
|
||||
},
|
||||
"people": {
|
||||
@@ -18040,14 +18020,10 @@
|
||||
},
|
||||
"id": {
|
||||
"description": "Stack ID",
|
||||
"format": "uuid",
|
||||
"pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-4[0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12})$",
|
||||
"type": "string"
|
||||
},
|
||||
"primaryAssetId": {
|
||||
"description": "Primary asset ID",
|
||||
"format": "uuid",
|
||||
"pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-4[0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12})$",
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
@@ -18183,8 +18159,6 @@
|
||||
},
|
||||
"id": {
|
||||
"description": "ID",
|
||||
"format": "uuid",
|
||||
"pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-4[0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12})$",
|
||||
"type": "string"
|
||||
},
|
||||
"success": {
|
||||
@@ -18363,8 +18337,6 @@
|
||||
},
|
||||
"userId": {
|
||||
"description": "User ID",
|
||||
"format": "uuid",
|
||||
"pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-4[0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12})$",
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
@@ -18469,8 +18441,6 @@
|
||||
},
|
||||
"userId": {
|
||||
"description": "User ID",
|
||||
"format": "uuid",
|
||||
"pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-4[0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12})$",
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
@@ -18631,8 +18601,6 @@
|
||||
"assetIds": {
|
||||
"description": "Asset IDs in this archive",
|
||||
"items": {
|
||||
"format": "uuid",
|
||||
"pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-4[0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12})$",
|
||||
"type": "string"
|
||||
},
|
||||
"type": "array"
|
||||
@@ -18818,8 +18786,6 @@
|
||||
},
|
||||
"duplicateId": {
|
||||
"description": "Duplicate group ID",
|
||||
"format": "uuid",
|
||||
"pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-4[0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12})$",
|
||||
"type": "string"
|
||||
},
|
||||
"suggestedKeepAssetIds": {
|
||||
@@ -19136,8 +19102,6 @@
|
||||
"properties": {
|
||||
"id": {
|
||||
"description": "Integrity report item id",
|
||||
"format": "uuid",
|
||||
"pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-4[0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12})$",
|
||||
"type": "string"
|
||||
},
|
||||
"path": {
|
||||
@@ -19312,8 +19276,6 @@
|
||||
},
|
||||
"id": {
|
||||
"description": "Library ID",
|
||||
"format": "uuid",
|
||||
"pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-4[0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12})$",
|
||||
"type": "string"
|
||||
},
|
||||
"importPaths": {
|
||||
@@ -19329,8 +19291,6 @@
|
||||
},
|
||||
"ownerId": {
|
||||
"description": "Owner user ID",
|
||||
"format": "uuid",
|
||||
"pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-4[0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12})$",
|
||||
"type": "string"
|
||||
},
|
||||
"refreshedAt": {
|
||||
@@ -19485,8 +19445,6 @@
|
||||
},
|
||||
"userId": {
|
||||
"description": "User ID",
|
||||
"format": "uuid",
|
||||
"pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-4[0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12})$",
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
@@ -19677,8 +19635,6 @@
|
||||
},
|
||||
"id": {
|
||||
"description": "Asset ID",
|
||||
"format": "uuid",
|
||||
"pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-4[0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12})$",
|
||||
"type": "string"
|
||||
},
|
||||
"lat": {
|
||||
@@ -19879,8 +19835,6 @@
|
||||
},
|
||||
"id": {
|
||||
"description": "Memory ID",
|
||||
"format": "uuid",
|
||||
"pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-4[0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12})$",
|
||||
"type": "string"
|
||||
},
|
||||
"isSaved": {
|
||||
@@ -19896,8 +19850,6 @@
|
||||
},
|
||||
"ownerId": {
|
||||
"description": "Owner user ID",
|
||||
"format": "uuid",
|
||||
"pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-4[0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12})$",
|
||||
"type": "string"
|
||||
},
|
||||
"seenAt": {
|
||||
@@ -20359,8 +20311,6 @@
|
||||
},
|
||||
"id": {
|
||||
"description": "Notification ID",
|
||||
"format": "uuid",
|
||||
"pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-4[0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12})$",
|
||||
"type": "string"
|
||||
},
|
||||
"level": {
|
||||
@@ -20805,8 +20755,6 @@
|
||||
},
|
||||
"id": {
|
||||
"description": "Person ID",
|
||||
"format": "uuid",
|
||||
"pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-4[0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12})$",
|
||||
"type": "string"
|
||||
},
|
||||
"isFavorite": {
|
||||
@@ -21042,8 +20990,6 @@
|
||||
},
|
||||
"id": {
|
||||
"description": "Person ID",
|
||||
"format": "uuid",
|
||||
"pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-4[0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12})$",
|
||||
"type": "string"
|
||||
},
|
||||
"isFavorite": {
|
||||
@@ -21299,8 +21245,6 @@
|
||||
},
|
||||
"id": {
|
||||
"description": "Plugin ID",
|
||||
"format": "uuid",
|
||||
"pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-4[0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12})$",
|
||||
"type": "string"
|
||||
},
|
||||
"methods": {
|
||||
@@ -22696,8 +22640,6 @@
|
||||
},
|
||||
"id": {
|
||||
"description": "Version history entry ID",
|
||||
"format": "uuid",
|
||||
"pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-4[0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12})$",
|
||||
"type": "string"
|
||||
},
|
||||
"version": {
|
||||
@@ -22802,8 +22744,6 @@
|
||||
},
|
||||
"id": {
|
||||
"description": "Session ID",
|
||||
"format": "uuid",
|
||||
"pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-4[0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12})$",
|
||||
"type": "string"
|
||||
},
|
||||
"isPendingSyncReset": {
|
||||
@@ -22861,8 +22801,6 @@
|
||||
},
|
||||
"id": {
|
||||
"description": "Session ID",
|
||||
"format": "uuid",
|
||||
"pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-4[0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12})$",
|
||||
"type": "string"
|
||||
},
|
||||
"isPendingSyncReset": {
|
||||
@@ -23085,8 +23023,6 @@
|
||||
},
|
||||
"id": {
|
||||
"description": "Shared link ID",
|
||||
"format": "uuid",
|
||||
"pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-4[0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12})$",
|
||||
"type": "string"
|
||||
},
|
||||
"key": {
|
||||
@@ -23112,8 +23048,6 @@
|
||||
},
|
||||
"userId": {
|
||||
"description": "Owner user ID",
|
||||
"format": "uuid",
|
||||
"pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-4[0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12})$",
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
@@ -23455,14 +23389,10 @@
|
||||
},
|
||||
"id": {
|
||||
"description": "Stack ID",
|
||||
"format": "uuid",
|
||||
"pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-4[0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12})$",
|
||||
"type": "string"
|
||||
},
|
||||
"primaryAssetId": {
|
||||
"description": "Primary asset ID",
|
||||
"format": "uuid",
|
||||
"pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-4[0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12})$",
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
@@ -23736,8 +23666,6 @@
|
||||
"properties": {
|
||||
"albumId": {
|
||||
"description": "Album ID",
|
||||
"format": "uuid",
|
||||
"pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-4[0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12})$",
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
@@ -23750,14 +23678,10 @@
|
||||
"properties": {
|
||||
"albumId": {
|
||||
"description": "Album ID",
|
||||
"format": "uuid",
|
||||
"pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-4[0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12})$",
|
||||
"type": "string"
|
||||
},
|
||||
"assetId": {
|
||||
"description": "Asset ID",
|
||||
"format": "uuid",
|
||||
"pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-4[0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12})$",
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
@@ -23771,14 +23695,10 @@
|
||||
"properties": {
|
||||
"albumId": {
|
||||
"description": "Album ID",
|
||||
"format": "uuid",
|
||||
"pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-4[0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12})$",
|
||||
"type": "string"
|
||||
},
|
||||
"assetId": {
|
||||
"description": "Asset ID",
|
||||
"format": "uuid",
|
||||
"pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-4[0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12})$",
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
@@ -23792,14 +23712,10 @@
|
||||
"properties": {
|
||||
"albumId": {
|
||||
"description": "Album ID",
|
||||
"format": "uuid",
|
||||
"pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-4[0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12})$",
|
||||
"type": "string"
|
||||
},
|
||||
"userId": {
|
||||
"description": "User ID",
|
||||
"format": "uuid",
|
||||
"pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-4[0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12})$",
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
@@ -23813,8 +23729,6 @@
|
||||
"properties": {
|
||||
"albumId": {
|
||||
"description": "Album ID",
|
||||
"format": "uuid",
|
||||
"pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-4[0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12})$",
|
||||
"type": "string"
|
||||
},
|
||||
"role": {
|
||||
@@ -23822,8 +23736,6 @@
|
||||
},
|
||||
"userId": {
|
||||
"description": "User ID",
|
||||
"format": "uuid",
|
||||
"pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-4[0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12})$",
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
@@ -23849,8 +23761,6 @@
|
||||
},
|
||||
"id": {
|
||||
"description": "Album ID",
|
||||
"format": "uuid",
|
||||
"pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-4[0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12})$",
|
||||
"type": "string"
|
||||
},
|
||||
"isActivityEnabled": {
|
||||
@@ -23866,8 +23776,6 @@
|
||||
},
|
||||
"ownerId": {
|
||||
"description": "Owner ID",
|
||||
"format": "uuid",
|
||||
"pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-4[0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12})$",
|
||||
"type": "string"
|
||||
},
|
||||
"thumbnailAssetId": {
|
||||
@@ -23911,8 +23819,6 @@
|
||||
},
|
||||
"id": {
|
||||
"description": "Album ID",
|
||||
"format": "uuid",
|
||||
"pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-4[0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12})$",
|
||||
"type": "string"
|
||||
},
|
||||
"isActivityEnabled": {
|
||||
@@ -23955,8 +23861,6 @@
|
||||
"properties": {
|
||||
"assetId": {
|
||||
"description": "Asset ID",
|
||||
"format": "uuid",
|
||||
"pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-4[0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12})$",
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
@@ -23969,8 +23873,6 @@
|
||||
"properties": {
|
||||
"editId": {
|
||||
"description": "Edit ID",
|
||||
"format": "uuid",
|
||||
"pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-4[0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12})$",
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
@@ -23986,14 +23888,10 @@
|
||||
},
|
||||
"assetId": {
|
||||
"description": "Asset ID",
|
||||
"format": "uuid",
|
||||
"pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-4[0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12})$",
|
||||
"type": "string"
|
||||
},
|
||||
"id": {
|
||||
"description": "Edit ID",
|
||||
"format": "uuid",
|
||||
"pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-4[0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12})$",
|
||||
"type": "string"
|
||||
},
|
||||
"parameters": {
|
||||
@@ -24021,8 +23919,6 @@
|
||||
"properties": {
|
||||
"assetId": {
|
||||
"description": "Asset ID",
|
||||
"format": "uuid",
|
||||
"pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-4[0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12})$",
|
||||
"type": "string"
|
||||
},
|
||||
"city": {
|
||||
@@ -24200,8 +24096,6 @@
|
||||
"properties": {
|
||||
"assetFaceId": {
|
||||
"description": "Asset face ID",
|
||||
"format": "uuid",
|
||||
"pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-4[0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12})$",
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
@@ -24214,8 +24108,6 @@
|
||||
"properties": {
|
||||
"assetId": {
|
||||
"description": "Asset ID",
|
||||
"format": "uuid",
|
||||
"pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-4[0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12})$",
|
||||
"type": "string"
|
||||
},
|
||||
"boundingBoxX1": {
|
||||
@@ -24244,8 +24136,6 @@
|
||||
},
|
||||
"id": {
|
||||
"description": "Asset face ID",
|
||||
"format": "uuid",
|
||||
"pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-4[0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12})$",
|
||||
"type": "string"
|
||||
},
|
||||
"imageHeight": {
|
||||
@@ -24288,8 +24178,6 @@
|
||||
"properties": {
|
||||
"assetId": {
|
||||
"description": "Asset ID",
|
||||
"format": "uuid",
|
||||
"pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-4[0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12})$",
|
||||
"type": "string"
|
||||
},
|
||||
"boundingBoxX1": {
|
||||
@@ -24326,8 +24214,6 @@
|
||||
},
|
||||
"id": {
|
||||
"description": "Asset face ID",
|
||||
"format": "uuid",
|
||||
"pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-4[0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12})$",
|
||||
"type": "string"
|
||||
},
|
||||
"imageHeight": {
|
||||
@@ -24376,8 +24262,6 @@
|
||||
"properties": {
|
||||
"assetId": {
|
||||
"description": "Asset ID",
|
||||
"format": "uuid",
|
||||
"pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-4[0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12})$",
|
||||
"type": "string"
|
||||
},
|
||||
"key": {
|
||||
@@ -24395,8 +24279,6 @@
|
||||
"properties": {
|
||||
"assetId": {
|
||||
"description": "Asset ID",
|
||||
"format": "uuid",
|
||||
"pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-4[0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12})$",
|
||||
"type": "string"
|
||||
},
|
||||
"key": {
|
||||
@@ -24445,8 +24327,6 @@
|
||||
"properties": {
|
||||
"assetId": {
|
||||
"description": "Asset ID",
|
||||
"format": "uuid",
|
||||
"pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-4[0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12})$",
|
||||
"type": "string"
|
||||
},
|
||||
"boxScore": {
|
||||
@@ -24456,8 +24336,6 @@
|
||||
},
|
||||
"id": {
|
||||
"description": "OCR entry ID",
|
||||
"format": "uuid",
|
||||
"pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-4[0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12})$",
|
||||
"type": "string"
|
||||
},
|
||||
"isVisible": {
|
||||
@@ -24584,8 +24462,6 @@
|
||||
},
|
||||
"id": {
|
||||
"description": "Asset ID",
|
||||
"format": "uuid",
|
||||
"pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-4[0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12})$",
|
||||
"type": "string"
|
||||
},
|
||||
"isEdited": {
|
||||
@@ -24620,8 +24496,6 @@
|
||||
},
|
||||
"ownerId": {
|
||||
"description": "Owner ID",
|
||||
"format": "uuid",
|
||||
"pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-4[0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12})$",
|
||||
"type": "string"
|
||||
},
|
||||
"stackId": {
|
||||
@@ -24726,8 +24600,6 @@
|
||||
},
|
||||
"id": {
|
||||
"description": "Asset ID",
|
||||
"format": "uuid",
|
||||
"pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-4[0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12})$",
|
||||
"type": "string"
|
||||
},
|
||||
"isEdited": {
|
||||
@@ -24762,8 +24634,6 @@
|
||||
},
|
||||
"ownerId": {
|
||||
"description": "Owner ID",
|
||||
"format": "uuid",
|
||||
"pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-4[0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12})$",
|
||||
"type": "string"
|
||||
},
|
||||
"stackId": {
|
||||
@@ -24842,8 +24712,6 @@
|
||||
},
|
||||
"id": {
|
||||
"description": "User ID",
|
||||
"format": "uuid",
|
||||
"pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-4[0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12})$",
|
||||
"type": "string"
|
||||
},
|
||||
"isAdmin": {
|
||||
@@ -24978,14 +24846,10 @@
|
||||
"properties": {
|
||||
"assetId": {
|
||||
"description": "Asset ID",
|
||||
"format": "uuid",
|
||||
"pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-4[0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12})$",
|
||||
"type": "string"
|
||||
},
|
||||
"memoryId": {
|
||||
"description": "Memory ID",
|
||||
"format": "uuid",
|
||||
"pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-4[0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12})$",
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
@@ -24999,14 +24863,10 @@
|
||||
"properties": {
|
||||
"assetId": {
|
||||
"description": "Asset ID",
|
||||
"format": "uuid",
|
||||
"pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-4[0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12})$",
|
||||
"type": "string"
|
||||
},
|
||||
"memoryId": {
|
||||
"description": "Memory ID",
|
||||
"format": "uuid",
|
||||
"pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-4[0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12})$",
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
@@ -25020,8 +24880,6 @@
|
||||
"properties": {
|
||||
"memoryId": {
|
||||
"description": "Memory ID",
|
||||
"format": "uuid",
|
||||
"pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-4[0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12})$",
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
@@ -25062,8 +24920,6 @@
|
||||
},
|
||||
"id": {
|
||||
"description": "Memory ID",
|
||||
"format": "uuid",
|
||||
"pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-4[0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12})$",
|
||||
"type": "string"
|
||||
},
|
||||
"isSaved": {
|
||||
@@ -25079,8 +24935,6 @@
|
||||
},
|
||||
"ownerId": {
|
||||
"description": "Owner ID",
|
||||
"format": "uuid",
|
||||
"pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-4[0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12})$",
|
||||
"type": "string"
|
||||
},
|
||||
"seenAt": {
|
||||
@@ -25130,14 +24984,10 @@
|
||||
"properties": {
|
||||
"sharedById": {
|
||||
"description": "Shared by ID",
|
||||
"format": "uuid",
|
||||
"pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-4[0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12})$",
|
||||
"type": "string"
|
||||
},
|
||||
"sharedWithId": {
|
||||
"description": "Shared with ID",
|
||||
"format": "uuid",
|
||||
"pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-4[0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12})$",
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
@@ -25155,14 +25005,10 @@
|
||||
},
|
||||
"sharedById": {
|
||||
"description": "Shared by ID",
|
||||
"format": "uuid",
|
||||
"pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-4[0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12})$",
|
||||
"type": "string"
|
||||
},
|
||||
"sharedWithId": {
|
||||
"description": "Shared with ID",
|
||||
"format": "uuid",
|
||||
"pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-4[0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12})$",
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
@@ -25177,8 +25023,6 @@
|
||||
"properties": {
|
||||
"personId": {
|
||||
"description": "Person ID",
|
||||
"format": "uuid",
|
||||
"pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-4[0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12})$",
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
@@ -25216,8 +25060,6 @@
|
||||
},
|
||||
"id": {
|
||||
"description": "Person ID",
|
||||
"format": "uuid",
|
||||
"pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-4[0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12})$",
|
||||
"type": "string"
|
||||
},
|
||||
"isFavorite": {
|
||||
@@ -25234,8 +25076,6 @@
|
||||
},
|
||||
"ownerId": {
|
||||
"description": "Owner ID",
|
||||
"format": "uuid",
|
||||
"pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-4[0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12})$",
|
||||
"type": "string"
|
||||
},
|
||||
"updatedAt": {
|
||||
@@ -25301,8 +25141,6 @@
|
||||
"properties": {
|
||||
"stackId": {
|
||||
"description": "Stack ID",
|
||||
"format": "uuid",
|
||||
"pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-4[0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12})$",
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
@@ -25322,20 +25160,14 @@
|
||||
},
|
||||
"id": {
|
||||
"description": "Stack ID",
|
||||
"format": "uuid",
|
||||
"pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-4[0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12})$",
|
||||
"type": "string"
|
||||
},
|
||||
"ownerId": {
|
||||
"description": "Owner ID",
|
||||
"format": "uuid",
|
||||
"pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-4[0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12})$",
|
||||
"type": "string"
|
||||
},
|
||||
"primaryAssetId": {
|
||||
"description": "Primary asset ID",
|
||||
"format": "uuid",
|
||||
"pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-4[0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12})$",
|
||||
"type": "string"
|
||||
},
|
||||
"updatedAt": {
|
||||
@@ -25378,8 +25210,6 @@
|
||||
"properties": {
|
||||
"userId": {
|
||||
"description": "User ID",
|
||||
"format": "uuid",
|
||||
"pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-4[0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12})$",
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
@@ -25395,8 +25225,6 @@
|
||||
},
|
||||
"userId": {
|
||||
"description": "User ID",
|
||||
"format": "uuid",
|
||||
"pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-4[0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12})$",
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
@@ -25413,8 +25241,6 @@
|
||||
},
|
||||
"userId": {
|
||||
"description": "User ID",
|
||||
"format": "uuid",
|
||||
"pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-4[0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12})$",
|
||||
"type": "string"
|
||||
},
|
||||
"value": {
|
||||
@@ -25458,8 +25284,6 @@
|
||||
},
|
||||
"id": {
|
||||
"description": "User ID",
|
||||
"format": "uuid",
|
||||
"pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-4[0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12})$",
|
||||
"type": "string"
|
||||
},
|
||||
"name": {
|
||||
@@ -26646,8 +26470,6 @@
|
||||
},
|
||||
"id": {
|
||||
"description": "Tag ID",
|
||||
"format": "uuid",
|
||||
"pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-4[0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12})$",
|
||||
"type": "string"
|
||||
},
|
||||
"name": {
|
||||
@@ -27171,8 +26993,6 @@
|
||||
},
|
||||
"userId": {
|
||||
"description": "User ID",
|
||||
"format": "uuid",
|
||||
"pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-4[0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12})$",
|
||||
"type": "string"
|
||||
},
|
||||
"userName": {
|
||||
@@ -27815,8 +27635,6 @@
|
||||
},
|
||||
"id": {
|
||||
"description": "Workflow ID",
|
||||
"format": "uuid",
|
||||
"pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-4[0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12})$",
|
||||
"type": "string"
|
||||
},
|
||||
"name": {
|
||||
|
||||
@@ -100,21 +100,21 @@ const AlbumUserResponseSchema = z
|
||||
|
||||
const ContributorCountResponseSchema = z
|
||||
.object({
|
||||
userId: z.uuidv4().describe('User ID'),
|
||||
userId: z.string().describe('User ID'),
|
||||
assetCount: z.int().min(0).describe('Number of assets contributed'),
|
||||
})
|
||||
.meta({ id: 'ContributorCountResponseDto' });
|
||||
|
||||
export const AlbumResponseSchema = z
|
||||
.object({
|
||||
id: z.uuidv4().describe('Album ID'),
|
||||
id: z.string().describe('Album ID'),
|
||||
albumName: z.string().describe('Album name'),
|
||||
description: z.string().describe('Album description'),
|
||||
// TODO: use `isoDatetimeToDate` when using `ZodSerializerDto` on the controllers.
|
||||
createdAt: z.string().meta({ format: 'date-time' }).describe('Creation date'),
|
||||
// TODO: use `isoDatetimeToDate` when using `ZodSerializerDto` on the controllers.
|
||||
updatedAt: z.string().meta({ format: 'date-time' }).describe('Last update date'),
|
||||
albumThumbnailAssetId: z.uuidv4().nullable().describe('Thumbnail asset ID'),
|
||||
albumThumbnailAssetId: z.string().nullable().describe('Thumbnail asset ID'),
|
||||
shared: z.boolean().describe('Is shared album'),
|
||||
albumUsers: z
|
||||
.array(AlbumUserResponseSchema)
|
||||
|
||||
@@ -21,7 +21,7 @@ const ApiKeyUpdateSchema = z
|
||||
|
||||
const ApiKeyResponseSchema = z
|
||||
.object({
|
||||
id: z.uuidv4().describe('API key ID'),
|
||||
id: z.string().describe('API key ID'),
|
||||
name: z.string().describe('API key name'),
|
||||
createdAt: isoDatetimeToDate.describe('Creation date'),
|
||||
updatedAt: isoDatetimeToDate.describe('Last update date'),
|
||||
|
||||
@@ -16,7 +16,7 @@ const AssetIdErrorReasonSchema = z
|
||||
/** @deprecated Use `BulkIdResponseDto` instead */
|
||||
const AssetIdsResponseSchema = z
|
||||
.object({
|
||||
assetId: z.uuidv4().describe('Asset ID'),
|
||||
assetId: z.string().describe('Asset ID'),
|
||||
success: z.boolean().describe('Whether operation succeeded'),
|
||||
error: AssetIdErrorReasonSchema.optional(),
|
||||
})
|
||||
@@ -43,7 +43,7 @@ export const BulkIdsSchema = z
|
||||
|
||||
const BulkIdResponseSchema = z
|
||||
.object({
|
||||
id: z.uuidv4().describe('ID'),
|
||||
id: z.string().describe('ID'),
|
||||
success: z.boolean().describe('Whether operation succeeded'),
|
||||
error: BulkIdErrorReasonSchema.optional(),
|
||||
errorMessage: z.string().optional(),
|
||||
|
||||
@@ -11,7 +11,7 @@ const AssetMediaStatusSchema = z.enum(AssetMediaStatus).describe('Upload status'
|
||||
const AssetMediaResponseSchema = z
|
||||
.object({
|
||||
status: AssetMediaStatusSchema,
|
||||
id: z.uuidv4().describe('Asset media ID'),
|
||||
id: z.string().describe('Asset media ID'),
|
||||
})
|
||||
.meta({ id: 'AssetMediaResponseDto' });
|
||||
|
||||
@@ -34,7 +34,7 @@ const AssetRejectReasonSchema = z
|
||||
|
||||
const AssetBulkUploadCheckResultSchema = z
|
||||
.object({
|
||||
id: z.uuidv4().describe('Asset ID'),
|
||||
id: z.string().describe('Asset ID'),
|
||||
action: AssetUploadActionSchema,
|
||||
reason: AssetRejectReasonSchema.optional(),
|
||||
assetId: z.string().optional().describe('Existing asset ID if duplicate'),
|
||||
|
||||
@@ -24,7 +24,7 @@ import z from 'zod';
|
||||
|
||||
const SanitizedAssetResponseSchema = z
|
||||
.object({
|
||||
id: z.uuidv4().describe('Asset ID'),
|
||||
id: z.string().describe('Asset ID'),
|
||||
type: AssetTypeSchema,
|
||||
thumbhash: z
|
||||
.string()
|
||||
@@ -52,8 +52,8 @@ export class SanitizedAssetResponseDto extends createZodDto(SanitizedAssetRespon
|
||||
|
||||
const AssetStackResponseSchema = z
|
||||
.object({
|
||||
id: z.uuidv4().describe('Stack ID'),
|
||||
primaryAssetId: z.uuidv4().describe('Primary asset ID'),
|
||||
id: z.string().describe('Stack ID'),
|
||||
primaryAssetId: z.string().describe('Primary asset ID'),
|
||||
assetCount: z.int().min(0).describe('Number of assets in stack'),
|
||||
})
|
||||
.meta({ id: 'AssetStackResponseDto' });
|
||||
@@ -65,7 +65,7 @@ export const AssetResponseSchema = SanitizedAssetResponseSchema.extend(
|
||||
.string()
|
||||
.meta({ format: 'date-time' })
|
||||
.describe('The UTC timestamp when the asset was originally uploaded to Immich.'),
|
||||
ownerId: z.uuidv4().describe('Owner user ID'),
|
||||
ownerId: z.string().describe('Owner user ID'),
|
||||
owner: UserResponseSchema.optional(),
|
||||
libraryId: z
|
||||
.uuidv4()
|
||||
@@ -103,7 +103,7 @@ export const AssetResponseSchema = SanitizedAssetResponseSchema.extend(
|
||||
people: z.array(PersonResponseSchema).optional(),
|
||||
checksum: z.string().describe('Base64 encoded SHA1 hash'),
|
||||
stack: AssetStackResponseSchema.nullish(),
|
||||
duplicateId: z.uuidv4().nullish().describe('Duplicate group ID'),
|
||||
duplicateId: z.string().nullish().describe('Duplicate group ID'),
|
||||
resized: z
|
||||
.boolean()
|
||||
.optional()
|
||||
|
||||
@@ -148,7 +148,7 @@ const AssetMetadataResponseSchema = z
|
||||
.meta({ id: 'AssetMetadataResponseDto' });
|
||||
|
||||
const AssetMetadataBulkResponseSchema = AssetMetadataResponseSchema.extend({
|
||||
assetId: z.uuidv4().describe('Asset ID'),
|
||||
assetId: z.string().describe('Asset ID'),
|
||||
}).meta({ id: 'AssetMetadataBulkResponseDto' });
|
||||
|
||||
const AssetCopySchema = z
|
||||
|
||||
@@ -29,7 +29,7 @@ const LoginCredentialSchema = z
|
||||
const LoginResponseSchema = z
|
||||
.object({
|
||||
accessToken: z.string().describe('Access token'),
|
||||
userId: z.uuidv4().describe('User ID'),
|
||||
userId: z.string().describe('User ID'),
|
||||
userEmail: toEmail.describe('User email'),
|
||||
name: z.string().describe('User name'),
|
||||
profileImagePath: z.string().describe('Profile image path'),
|
||||
|
||||
@@ -14,7 +14,7 @@ const DownloadInfoSchema = z
|
||||
const DownloadArchiveInfoSchema = z
|
||||
.object({
|
||||
size: z.int().describe('Archive size in bytes'),
|
||||
assetIds: z.array(z.uuidv4()).describe('Asset IDs in this archive'),
|
||||
assetIds: z.array(z.string()).describe('Asset IDs in this archive'),
|
||||
})
|
||||
.meta({ id: 'DownloadArchiveInfo' });
|
||||
|
||||
|
||||
@@ -4,7 +4,7 @@ import z from 'zod';
|
||||
|
||||
const DuplicateResponseSchema = z
|
||||
.object({
|
||||
duplicateId: z.uuidv4().describe('Duplicate group ID'),
|
||||
duplicateId: z.string().describe('Duplicate group ID'),
|
||||
assets: z.array(AssetResponseSchema).describe('Duplicate assets'),
|
||||
suggestedKeepAssetIds: z.array(z.uuidv4()).describe('Suggested asset IDs to keep based on file size and EXIF data'),
|
||||
})
|
||||
|
||||
@@ -27,7 +27,7 @@ const IntegrityDeleteReportSchema = z.object({ type: IntegrityReport }).meta({ i
|
||||
export class IntegrityDeleteReportDto extends createZodDto(IntegrityDeleteReportSchema) {}
|
||||
|
||||
const IntegrityReportResponseItemSchema = z.object({
|
||||
id: z.uuidv4().describe('Integrity report item id'),
|
||||
id: z.string().describe('Integrity report item id'),
|
||||
type: IntegrityReportSchema,
|
||||
path: z.string().describe('Integrity report item path'),
|
||||
});
|
||||
|
||||
@@ -62,8 +62,8 @@ const ValidateLibraryResponseSchema = z
|
||||
|
||||
const LibraryResponseSchema = z
|
||||
.object({
|
||||
id: z.uuidv4().describe('Library ID'),
|
||||
ownerId: z.uuidv4().describe('Owner user ID'),
|
||||
id: z.string().describe('Library ID'),
|
||||
ownerId: z.string().describe('Owner user ID'),
|
||||
name: z.string().describe('Library name'),
|
||||
assetCount: z.int().describe('Number of assets'),
|
||||
importPaths: z.array(z.string()).describe('Import paths'),
|
||||
|
||||
@@ -30,7 +30,7 @@ const MapMarkerSchema = z
|
||||
|
||||
const MapMarkerResponseSchema = z
|
||||
.object({
|
||||
id: z.uuidv4().describe('Asset ID'),
|
||||
id: z.string().describe('Asset ID'),
|
||||
lat: z.number().meta({ format: 'double' }).describe('Latitude'),
|
||||
lon: z.number().meta({ format: 'double' }).describe('Longitude'),
|
||||
city: z.string().nullable().describe('City name'),
|
||||
|
||||
@@ -59,7 +59,7 @@ const MemoryStatisticsResponseSchema = z
|
||||
|
||||
const MemoryResponseSchema = z
|
||||
.object({
|
||||
id: z.uuidv4().describe('Memory ID'),
|
||||
id: z.string().describe('Memory ID'),
|
||||
createdAt: isoDatetimeToDate.describe('Creation date'),
|
||||
updatedAt: isoDatetimeToDate.describe('Last update date'),
|
||||
deletedAt: isoDatetimeToDate.optional().describe('Deletion date'),
|
||||
@@ -67,7 +67,7 @@ const MemoryResponseSchema = z
|
||||
seenAt: isoDatetimeToDate.optional().describe('Date when memory was seen'),
|
||||
showAt: isoDatetimeToDate.optional().describe('Date when memory should be shown'),
|
||||
hideAt: isoDatetimeToDate.optional().describe('Date when memory should be hidden'),
|
||||
ownerId: z.uuidv4().describe('Owner user ID'),
|
||||
ownerId: z.string().describe('Owner user ID'),
|
||||
type: MemoryTypeSchema,
|
||||
data: OnThisDaySchema,
|
||||
isSaved: z.boolean().describe('Is memory saved'),
|
||||
|
||||
@@ -24,7 +24,7 @@ const TemplateSchema = z
|
||||
|
||||
const NotificationSchema = z
|
||||
.object({
|
||||
id: z.uuidv4().describe('Notification ID'),
|
||||
id: z.string().describe('Notification ID'),
|
||||
createdAt: isoDatetimeToDate.describe('Creation date'),
|
||||
level: NotificationLevelSchema,
|
||||
type: NotificationTypeSchema,
|
||||
|
||||
@@ -33,7 +33,7 @@ const PersonUpdateSchema = PersonCreateSchema.extend({
|
||||
}).meta({ id: 'PersonUpdateDto' });
|
||||
|
||||
const PeopleUpdateItemSchema = PersonUpdateSchema.extend({
|
||||
id: z.uuidv4().describe('Person ID'),
|
||||
id: z.string().describe('Person ID'),
|
||||
}).meta({ id: 'PeopleUpdateItem' });
|
||||
|
||||
const PeopleUpdateSchema = z
|
||||
@@ -60,7 +60,7 @@ const PersonSearchSchema = z
|
||||
|
||||
export const PersonResponseSchema = z
|
||||
.object({
|
||||
id: z.uuidv4().describe('Person ID'),
|
||||
id: z.string().describe('Person ID'),
|
||||
name: z.string().describe('Person name'),
|
||||
// TODO: use `isoDateToDate` when using `ZodSerializerDto` on the controllers.
|
||||
birthDate: z.string().meta({ format: 'date' }).describe('Person date of birth').nullable(),
|
||||
|
||||
@@ -32,7 +32,7 @@ const PluginMethodResponseSchema = z
|
||||
|
||||
const PluginResponseSchema = z
|
||||
.object({
|
||||
id: z.uuidv4().describe('Plugin ID'),
|
||||
id: z.string().describe('Plugin ID'),
|
||||
name: z.string().describe('Plugin name'),
|
||||
title: z.string().describe('Plugin title'),
|
||||
description: z.string().describe('Plugin description'),
|
||||
|
||||
@@ -73,7 +73,7 @@ const ServerVersionResponseSchema = z
|
||||
|
||||
const ServerVersionHistoryResponseSchema = z
|
||||
.object({
|
||||
id: z.uuidv4().describe('Version history entry ID'),
|
||||
id: z.string().describe('Version history entry ID'),
|
||||
createdAt: isoDatetimeToDate.describe('When this version was first seen'),
|
||||
version: z.string().describe('Version string'),
|
||||
})
|
||||
@@ -81,7 +81,7 @@ const ServerVersionHistoryResponseSchema = z
|
||||
|
||||
const UsageByUserSchema = z
|
||||
.object({
|
||||
userId: z.uuidv4().describe('User ID'),
|
||||
userId: z.string().describe('User ID'),
|
||||
userName: z.string().describe('User name'),
|
||||
photos: z.int().describe('Number of photos'),
|
||||
videos: z.int().describe('Number of videos'),
|
||||
|
||||
@@ -18,7 +18,7 @@ const SessionUpdateSchema = z
|
||||
|
||||
const SessionResponseSchema = z
|
||||
.object({
|
||||
id: z.uuidv4().describe('Session ID'),
|
||||
id: z.string().describe('Session ID'),
|
||||
createdAt: z.string().describe('Creation date'),
|
||||
updatedAt: z.string().describe('Last update date'),
|
||||
expiresAt: z.string().optional().describe('Expiration date'),
|
||||
|
||||
@@ -53,10 +53,10 @@ const SharedLinkLoginSchema = z
|
||||
|
||||
const SharedLinkResponseSchema = z
|
||||
.object({
|
||||
id: z.uuidv4().describe('Shared link ID'),
|
||||
id: z.string().describe('Shared link ID'),
|
||||
description: z.string().nullable().describe('Link description'),
|
||||
password: z.string().nullable().describe('Has password'),
|
||||
userId: z.uuidv4().describe('Owner user ID'),
|
||||
userId: z.string().describe('Owner user ID'),
|
||||
key: z.string().describe('Encryption key (base64url)'),
|
||||
type: SharedLinkTypeSchema,
|
||||
createdAt: isoDatetimeToDate.describe('Creation date'),
|
||||
|
||||
@@ -24,8 +24,8 @@ const StackUpdateSchema = z
|
||||
|
||||
const StackResponseSchema = z
|
||||
.object({
|
||||
id: z.uuidv4().describe('Stack ID'),
|
||||
primaryAssetId: z.uuidv4().describe('Primary asset ID'),
|
||||
id: z.string().describe('Stack ID'),
|
||||
primaryAssetId: z.string().describe('Primary asset ID'),
|
||||
assets: z.array(AssetResponseSchema),
|
||||
})
|
||||
.describe('Stack response')
|
||||
|
||||
+50
-50
@@ -19,7 +19,7 @@ import z from 'zod';
|
||||
|
||||
const SyncUserV1Schema = z
|
||||
.object({
|
||||
id: z.uuidv4().describe('User ID'),
|
||||
id: z.string().describe('User ID'),
|
||||
name: z.string().describe('User name'),
|
||||
email: z.string().describe('User email'),
|
||||
avatarColor: UserAvatarColorSchema.nullish(),
|
||||
@@ -40,27 +40,27 @@ const SyncAuthUserV1Schema = SyncUserV1Schema.merge(
|
||||
}),
|
||||
).meta({ id: 'SyncAuthUserV1' });
|
||||
|
||||
const SyncUserDeleteV1Schema = z.object({ userId: z.uuidv4().describe('User ID') }).meta({ id: 'SyncUserDeleteV1' });
|
||||
const SyncUserDeleteV1Schema = z.object({ userId: z.string().describe('User ID') }).meta({ id: 'SyncUserDeleteV1' });
|
||||
|
||||
const SyncPartnerV1Schema = z
|
||||
.object({
|
||||
sharedById: z.uuidv4().describe('Shared by ID'),
|
||||
sharedWithId: z.uuidv4().describe('Shared with ID'),
|
||||
sharedById: z.string().describe('Shared by ID'),
|
||||
sharedWithId: z.string().describe('Shared with ID'),
|
||||
inTimeline: z.boolean().describe('In timeline'),
|
||||
})
|
||||
.meta({ id: 'SyncPartnerV1' });
|
||||
|
||||
const SyncPartnerDeleteV1Schema = z
|
||||
.object({
|
||||
sharedById: z.uuidv4().describe('Shared by ID'),
|
||||
sharedWithId: z.uuidv4().describe('Shared with ID'),
|
||||
sharedById: z.string().describe('Shared by ID'),
|
||||
sharedWithId: z.string().describe('Shared with ID'),
|
||||
})
|
||||
.meta({ id: 'SyncPartnerDeleteV1' });
|
||||
|
||||
const SyncAssetV1Schema = z
|
||||
.object({
|
||||
id: z.uuidv4().describe('Asset ID'),
|
||||
ownerId: z.uuidv4().describe('Owner ID'),
|
||||
id: z.string().describe('Asset ID'),
|
||||
ownerId: z.string().describe('Owner ID'),
|
||||
originalFileName: z.string().describe('Original file name'),
|
||||
thumbhash: z.string().nullable().describe('Thumbhash'),
|
||||
checksum: z.string().describe('Checksum'),
|
||||
@@ -84,8 +84,8 @@ const SyncAssetV1Schema = z
|
||||
|
||||
const SyncAssetV2Schema = z
|
||||
.object({
|
||||
id: z.uuidv4().describe('Asset ID'),
|
||||
ownerId: z.uuidv4().describe('Owner ID'),
|
||||
id: z.string().describe('Asset ID'),
|
||||
ownerId: z.string().describe('Owner ID'),
|
||||
originalFileName: z.string().describe('Original file name'),
|
||||
thumbhash: z.string().nullable().describe('Thumbhash'),
|
||||
checksum: z.string().describe('Checksum'),
|
||||
@@ -123,12 +123,12 @@ export class SyncAssetV1 extends createZodDto(SyncAssetV1Schema) {}
|
||||
export class SyncAssetV2 extends createZodDto(SyncAssetV2Schema) {}
|
||||
|
||||
const SyncAssetDeleteV1Schema = z
|
||||
.object({ assetId: z.uuidv4().describe('Asset ID') })
|
||||
.object({ assetId: z.string().describe('Asset ID') })
|
||||
.meta({ id: 'SyncAssetDeleteV1' });
|
||||
|
||||
const SyncAssetExifV1Schema = z
|
||||
.object({
|
||||
assetId: z.uuidv4().describe('Asset ID'),
|
||||
assetId: z.string().describe('Asset ID'),
|
||||
description: z.string().nullable().describe('Description'),
|
||||
exifImageWidth: z.int().nullable().describe('Exif image width'),
|
||||
exifImageHeight: z.int().nullable().describe('Exif image height'),
|
||||
@@ -158,7 +158,7 @@ const SyncAssetExifV1Schema = z
|
||||
|
||||
const SyncAssetMetadataV1Schema = z
|
||||
.object({
|
||||
assetId: z.uuidv4().describe('Asset ID'),
|
||||
assetId: z.string().describe('Asset ID'),
|
||||
key: z.string().describe('Key'),
|
||||
value: z.record(z.string(), z.unknown()).describe('Value'),
|
||||
})
|
||||
@@ -166,15 +166,15 @@ const SyncAssetMetadataV1Schema = z
|
||||
|
||||
const SyncAssetMetadataDeleteV1Schema = z
|
||||
.object({
|
||||
assetId: z.uuidv4().describe('Asset ID'),
|
||||
assetId: z.string().describe('Asset ID'),
|
||||
key: z.string().describe('Key'),
|
||||
})
|
||||
.meta({ id: 'SyncAssetMetadataDeleteV1' });
|
||||
|
||||
const SyncAssetEditV1Schema = z
|
||||
.object({
|
||||
id: z.uuidv4().describe('Edit ID'),
|
||||
assetId: z.uuidv4().describe('Asset ID'),
|
||||
id: z.string().describe('Edit ID'),
|
||||
assetId: z.string().describe('Asset ID'),
|
||||
action: AssetEditActionSchema,
|
||||
parameters: z.record(z.string(), z.unknown()).describe('Edit parameters'),
|
||||
sequence: z.int().describe('Edit sequence'),
|
||||
@@ -182,7 +182,7 @@ const SyncAssetEditV1Schema = z
|
||||
.meta({ id: 'SyncAssetEditV1' });
|
||||
|
||||
const SyncAssetEditDeleteV1Schema = z
|
||||
.object({ editId: z.uuidv4().describe('Edit ID') })
|
||||
.object({ editId: z.string().describe('Edit ID') })
|
||||
.meta({ id: 'SyncAssetEditDeleteV1' });
|
||||
|
||||
@ExtraModel()
|
||||
@@ -199,28 +199,28 @@ export class SyncAssetEditV1 extends createZodDto(SyncAssetEditV1Schema) {}
|
||||
class SyncAssetEditDeleteV1 extends createZodDto(SyncAssetEditDeleteV1Schema) {}
|
||||
|
||||
const SyncAlbumDeleteV1Schema = z
|
||||
.object({ albumId: z.uuidv4().describe('Album ID') })
|
||||
.object({ albumId: z.string().describe('Album ID') })
|
||||
.meta({ id: 'SyncAlbumDeleteV1' });
|
||||
|
||||
const SyncAlbumUserDeleteV1Schema = z
|
||||
.object({
|
||||
albumId: z.uuidv4().describe('Album ID'),
|
||||
userId: z.uuidv4().describe('User ID'),
|
||||
albumId: z.string().describe('Album ID'),
|
||||
userId: z.string().describe('User ID'),
|
||||
})
|
||||
.meta({ id: 'SyncAlbumUserDeleteV1' });
|
||||
|
||||
const SyncAlbumUserV1Schema = z
|
||||
.object({
|
||||
albumId: z.uuidv4().describe('Album ID'),
|
||||
userId: z.uuidv4().describe('User ID'),
|
||||
albumId: z.string().describe('Album ID'),
|
||||
userId: z.string().describe('User ID'),
|
||||
role: AlbumUserRoleSchema,
|
||||
})
|
||||
.meta({ id: 'SyncAlbumUserV1' });
|
||||
|
||||
const SyncAlbumV1Schema = z
|
||||
.object({
|
||||
id: z.uuidv4().describe('Album ID'),
|
||||
ownerId: z.uuidv4().describe('Owner ID'),
|
||||
id: z.string().describe('Album ID'),
|
||||
ownerId: z.string().describe('Owner ID'),
|
||||
name: z.string().describe('Album name'),
|
||||
description: z.string().describe('Album description'),
|
||||
createdAt: isoDatetimeToDate.describe('Created at'),
|
||||
@@ -233,7 +233,7 @@ const SyncAlbumV1Schema = z
|
||||
|
||||
const SyncAlbumV2Schema = z
|
||||
.object({
|
||||
id: z.uuidv4().describe('Album ID'),
|
||||
id: z.string().describe('Album ID'),
|
||||
name: z.string().describe('Album name'),
|
||||
description: z.string().describe('Album description'),
|
||||
createdAt: isoDatetimeToDate.describe('Created at'),
|
||||
@@ -246,15 +246,15 @@ const SyncAlbumV2Schema = z
|
||||
|
||||
const SyncAlbumToAssetV1Schema = z
|
||||
.object({
|
||||
albumId: z.uuidv4().describe('Album ID'),
|
||||
assetId: z.uuidv4().describe('Asset ID'),
|
||||
albumId: z.string().describe('Album ID'),
|
||||
assetId: z.string().describe('Asset ID'),
|
||||
})
|
||||
.meta({ id: 'SyncAlbumToAssetV1' });
|
||||
|
||||
const SyncAlbumToAssetDeleteV1Schema = z
|
||||
.object({
|
||||
albumId: z.uuidv4().describe('Album ID'),
|
||||
assetId: z.uuidv4().describe('Asset ID'),
|
||||
albumId: z.string().describe('Album ID'),
|
||||
assetId: z.string().describe('Asset ID'),
|
||||
})
|
||||
.meta({ id: 'SyncAlbumToAssetDeleteV1' });
|
||||
|
||||
@@ -284,11 +284,11 @@ export function syncAlbumV2ToV1(
|
||||
|
||||
const SyncMemoryV1Schema = z
|
||||
.object({
|
||||
id: z.uuidv4().describe('Memory ID'),
|
||||
id: z.string().describe('Memory ID'),
|
||||
createdAt: isoDatetimeToDate.describe('Created at'),
|
||||
updatedAt: isoDatetimeToDate.describe('Updated at'),
|
||||
deletedAt: isoDatetimeToDate.nullable().describe('Deleted at'),
|
||||
ownerId: z.uuidv4().describe('Owner ID'),
|
||||
ownerId: z.string().describe('Owner ID'),
|
||||
type: MemoryTypeSchema,
|
||||
data: z.record(z.string(), z.unknown()).describe('Data'),
|
||||
isSaved: z.boolean().describe('Is saved'),
|
||||
@@ -300,43 +300,43 @@ const SyncMemoryV1Schema = z
|
||||
.meta({ id: 'SyncMemoryV1' });
|
||||
|
||||
const SyncMemoryDeleteV1Schema = z
|
||||
.object({ memoryId: z.uuidv4().describe('Memory ID') })
|
||||
.object({ memoryId: z.string().describe('Memory ID') })
|
||||
.meta({ id: 'SyncMemoryDeleteV1' });
|
||||
|
||||
const SyncMemoryAssetV1Schema = z
|
||||
.object({
|
||||
memoryId: z.uuidv4().describe('Memory ID'),
|
||||
assetId: z.uuidv4().describe('Asset ID'),
|
||||
memoryId: z.string().describe('Memory ID'),
|
||||
assetId: z.string().describe('Asset ID'),
|
||||
})
|
||||
.meta({ id: 'SyncMemoryAssetV1' });
|
||||
|
||||
const SyncMemoryAssetDeleteV1Schema = z
|
||||
.object({
|
||||
memoryId: z.uuidv4().describe('Memory ID'),
|
||||
assetId: z.uuidv4().describe('Asset ID'),
|
||||
memoryId: z.string().describe('Memory ID'),
|
||||
assetId: z.string().describe('Asset ID'),
|
||||
})
|
||||
.meta({ id: 'SyncMemoryAssetDeleteV1' });
|
||||
|
||||
const SyncStackV1Schema = z
|
||||
.object({
|
||||
id: z.uuidv4().describe('Stack ID'),
|
||||
id: z.string().describe('Stack ID'),
|
||||
createdAt: isoDatetimeToDate.describe('Created at'),
|
||||
updatedAt: isoDatetimeToDate.describe('Updated at'),
|
||||
primaryAssetId: z.uuidv4().describe('Primary asset ID'),
|
||||
ownerId: z.uuidv4().describe('Owner ID'),
|
||||
primaryAssetId: z.string().describe('Primary asset ID'),
|
||||
ownerId: z.string().describe('Owner ID'),
|
||||
})
|
||||
.meta({ id: 'SyncStackV1' });
|
||||
|
||||
const SyncStackDeleteV1Schema = z
|
||||
.object({ stackId: z.uuidv4().describe('Stack ID') })
|
||||
.object({ stackId: z.string().describe('Stack ID') })
|
||||
.meta({ id: 'SyncStackDeleteV1' });
|
||||
|
||||
const SyncPersonV1Schema = z
|
||||
.object({
|
||||
id: z.uuidv4().describe('Person ID'),
|
||||
id: z.string().describe('Person ID'),
|
||||
createdAt: isoDatetimeToDate.describe('Created at'),
|
||||
updatedAt: isoDatetimeToDate.describe('Updated at'),
|
||||
ownerId: z.uuidv4().describe('Owner ID'),
|
||||
ownerId: z.string().describe('Owner ID'),
|
||||
name: z.string().describe('Person name'),
|
||||
birthDate: isoDatetimeToDate.nullable().describe('Birth date'),
|
||||
isHidden: z.boolean().describe('Is hidden'),
|
||||
@@ -347,13 +347,13 @@ const SyncPersonV1Schema = z
|
||||
.meta({ id: 'SyncPersonV1' });
|
||||
|
||||
const SyncPersonDeleteV1Schema = z
|
||||
.object({ personId: z.uuidv4().describe('Person ID') })
|
||||
.object({ personId: z.string().describe('Person ID') })
|
||||
.meta({ id: 'SyncPersonDeleteV1' });
|
||||
|
||||
const SyncAssetFaceV1Schema = z
|
||||
.object({
|
||||
id: z.uuidv4().describe('Asset face ID'),
|
||||
assetId: z.uuidv4().describe('Asset ID'),
|
||||
id: z.string().describe('Asset face ID'),
|
||||
assetId: z.string().describe('Asset ID'),
|
||||
personId: z.string().nullable().describe('Person ID'),
|
||||
imageWidth: z.int().describe('Image width'),
|
||||
imageHeight: z.int().describe('Image height'),
|
||||
@@ -371,12 +371,12 @@ const SyncAssetFaceV2Schema = SyncAssetFaceV1Schema.extend({
|
||||
}).meta({ id: 'SyncAssetFaceV2' });
|
||||
|
||||
const SyncAssetFaceDeleteV1Schema = z
|
||||
.object({ assetFaceId: z.uuidv4().describe('Asset face ID') })
|
||||
.object({ assetFaceId: z.string().describe('Asset face ID') })
|
||||
.meta({ id: 'SyncAssetFaceDeleteV1' });
|
||||
|
||||
const SyncUserMetadataV1Schema = z
|
||||
.object({
|
||||
userId: z.uuidv4().describe('User ID'),
|
||||
userId: z.string().describe('User ID'),
|
||||
key: UserMetadataKeySchema,
|
||||
value: z.record(z.string(), z.unknown()).describe('User metadata value'),
|
||||
})
|
||||
@@ -384,7 +384,7 @@ const SyncUserMetadataV1Schema = z
|
||||
|
||||
const SyncUserMetadataDeleteV1Schema = z
|
||||
.object({
|
||||
userId: z.uuidv4().describe('User ID'),
|
||||
userId: z.string().describe('User ID'),
|
||||
key: UserMetadataKeySchema,
|
||||
})
|
||||
.meta({ id: 'SyncUserMetadataDeleteV1' });
|
||||
@@ -404,8 +404,8 @@ class SyncMemoryAssetDeleteV1 extends createZodDto(SyncMemoryAssetDeleteV1Schema
|
||||
|
||||
const SyncAssetOcrV1Schema = z
|
||||
.object({
|
||||
id: z.uuidv4().describe('OCR entry ID'),
|
||||
assetId: z.uuidv4().describe('Asset ID'),
|
||||
id: z.string().describe('OCR entry ID'),
|
||||
assetId: z.string().describe('Asset ID'),
|
||||
|
||||
x1: z.number().meta({ format: 'double' }).describe('Top-left X coordinate (normalized 0–1)'),
|
||||
y1: z.number().meta({ format: 'double' }).describe('Top-left Y coordinate (normalized 0–1)'),
|
||||
|
||||
@@ -40,7 +40,7 @@ const TagBulkAssetsResponseSchema = z
|
||||
|
||||
export const TagResponseSchema = z
|
||||
.object({
|
||||
id: z.uuidv4().describe('Tag ID'),
|
||||
id: z.string().describe('Tag ID'),
|
||||
parentId: z.string().optional().describe('Parent tag ID'),
|
||||
name: z.string().describe('Tag name'),
|
||||
value: z.string().describe('Tag value (full path)'),
|
||||
|
||||
@@ -11,7 +11,7 @@ export class CreateProfileImageDto {
|
||||
|
||||
const CreateProfileImageResponseSchema = z
|
||||
.object({
|
||||
userId: z.uuidv4().describe('User ID'),
|
||||
userId: z.string().describe('User ID'),
|
||||
profileChangedAt: isoDatetimeToDate.describe('Profile image change date'),
|
||||
profileImagePath: z.string().describe('Profile image file path'),
|
||||
})
|
||||
|
||||
@@ -58,7 +58,7 @@ const WorkflowUpdateSchema = z
|
||||
|
||||
const WorkflowResponseSchema = z
|
||||
.object({
|
||||
id: z.uuidv4().describe('Workflow ID'),
|
||||
id: z.string().describe('Workflow ID'),
|
||||
trigger: WorkflowTriggerSchema.describe('Workflow trigger type'),
|
||||
name: z.string().nullable().describe('Workflow name'),
|
||||
description: z.string().nullable().describe('Workflow description'),
|
||||
|
||||
@@ -369,26 +369,6 @@ describe(DuplicateService.name, () => {
|
||||
expect(mocks.job.queueAll).toHaveBeenCalledWith([{ name: JobName.SidecarWrite, data: { id: asset1.id } }]);
|
||||
});
|
||||
|
||||
it('should not merge metadata when multiple assets are kept', async () => {
|
||||
const asset1 = AssetFactory.create({ isFavorite: true });
|
||||
const asset2 = AssetFactory.create();
|
||||
mocks.access.duplicate.checkOwnerAccess.mockResolvedValue(new Set(['group-1']));
|
||||
mocks.duplicateRepository.get.mockResolvedValue({
|
||||
duplicateId: 'group-1',
|
||||
assets: [asset1 as unknown as MapAsset, asset2 as unknown as MapAsset],
|
||||
});
|
||||
|
||||
const result = await sut.resolve(authStub.admin, {
|
||||
groups: [{ duplicateId: 'group-1', keepAssetIds: [asset1.id, asset2.id], trashAssetIds: [] }],
|
||||
});
|
||||
|
||||
expect(result[0].success).toBe(true);
|
||||
expect(mocks.album.addAssetIdsToAlbums).not.toHaveBeenCalled();
|
||||
expect(mocks.tag.replaceAssetTags).not.toHaveBeenCalled();
|
||||
expect(mocks.asset.updateAllExif).not.toHaveBeenCalled();
|
||||
expect(mocks.asset.updateAll).toHaveBeenCalledWith([asset1.id, asset2.id], { duplicateId: null });
|
||||
});
|
||||
|
||||
// NOTE: The following integration-style tests are covered by E2E tests instead
|
||||
// to avoid complex mock setup. The validation and error-handling logic above
|
||||
// is thoroughly unit tested.
|
||||
|
||||
@@ -156,51 +156,51 @@ export class DuplicateService extends BaseService {
|
||||
}
|
||||
}
|
||||
|
||||
// Only merge metadata into the keeper when exactly one asset can absorb trashed duplicates.
|
||||
if (idsToKeep.length === 1 && idsToTrash.length > 0) {
|
||||
const assetAlbumMap = await this.albumRepository.getByAssetIds(auth.user.id, [...groupAssetIds]);
|
||||
const assetAlbumMap = await this.albumRepository.getByAssetIds(auth.user.id, [...groupAssetIds]);
|
||||
|
||||
const { assetUpdate, exifUpdate, mergedAlbumIds, mergedTagIds, mergedTagValues } = this.getSyncMergeResult(
|
||||
duplicateGroup.assets,
|
||||
assetAlbumMap,
|
||||
);
|
||||
const { assetUpdate, exifUpdate, mergedAlbumIds, mergedTagIds, mergedTagValues } = this.getSyncMergeResult(
|
||||
duplicateGroup.assets,
|
||||
assetAlbumMap,
|
||||
);
|
||||
|
||||
if (mergedAlbumIds.length > 0) {
|
||||
const allowedAlbumIds = await this.checkAccess({
|
||||
auth,
|
||||
permission: Permission.AlbumAssetCreate,
|
||||
ids: mergedAlbumIds,
|
||||
});
|
||||
if (mergedAlbumIds.length > 0) {
|
||||
const allowedAlbumIds = await this.checkAccess({
|
||||
auth,
|
||||
permission: Permission.AlbumAssetCreate,
|
||||
ids: mergedAlbumIds,
|
||||
});
|
||||
|
||||
const allowedShareIds = await this.checkAccess({
|
||||
auth,
|
||||
permission: Permission.AssetShare,
|
||||
ids: idsToKeep,
|
||||
});
|
||||
const allowedShareIds = await this.checkAccess({
|
||||
auth,
|
||||
permission: Permission.AssetShare,
|
||||
ids: idsToKeep,
|
||||
});
|
||||
|
||||
if (allowedAlbumIds.size > 0 && allowedShareIds.size > 0) {
|
||||
await this.albumRepository.addAssetIdsToAlbums(
|
||||
[...allowedAlbumIds].flatMap((albumId) => [...allowedShareIds].map((assetId) => ({ albumId, assetId }))),
|
||||
);
|
||||
}
|
||||
if (allowedAlbumIds.size > 0 && allowedShareIds.size > 0) {
|
||||
await this.albumRepository.addAssetIdsToAlbums(
|
||||
[...allowedAlbumIds].flatMap((albumId) => [...allowedShareIds].map((assetId) => ({ albumId, assetId }))),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
if (mergedTagIds.length > 0) {
|
||||
const allowedTagIds = await this.checkAccess({
|
||||
auth,
|
||||
permission: Permission.TagAsset,
|
||||
ids: mergedTagIds,
|
||||
});
|
||||
if (mergedTagIds.length > 0) {
|
||||
const allowedTagIds = await this.checkAccess({
|
||||
auth,
|
||||
permission: Permission.TagAsset,
|
||||
ids: mergedTagIds,
|
||||
});
|
||||
|
||||
if (allowedTagIds.size > 0) {
|
||||
await Promise.all(
|
||||
idsToKeep.map((assetId) => this.tagRepository.replaceAssetTags(assetId, [...allowedTagIds])),
|
||||
);
|
||||
if (allowedTagIds.size > 0) {
|
||||
// Replace tags for each keeper asset to ensure all merged tags are applied
|
||||
await Promise.all(idsToKeep.map((assetId) => this.tagRepository.replaceAssetTags(assetId, [...allowedTagIds])));
|
||||
|
||||
await this.assetRepository.updateAllExif(idsToKeep, { tags: mergedTagValues });
|
||||
}
|
||||
// Update asset_exif.tags so the subsequent SidecarWrite + MetadataExtraction
|
||||
// cycle preserves the merged tags (updateAllExif locks the property automatically)
|
||||
await this.assetRepository.updateAllExif(idsToKeep, { tags: mergedTagValues });
|
||||
}
|
||||
}
|
||||
|
||||
if (idsToKeep.length > 0) {
|
||||
const hasExifUpdate = Object.keys(exifUpdate).length > 0;
|
||||
const hasTagUpdate = mergedTagIds.length > 0;
|
||||
|
||||
@@ -213,8 +213,6 @@ export class DuplicateService extends BaseService {
|
||||
}
|
||||
|
||||
await this.assetRepository.updateAll(idsToKeep, { duplicateId: null, ...assetUpdate });
|
||||
} else if (idsToKeep.length > 0) {
|
||||
await this.assetRepository.updateAll(idsToKeep, { duplicateId: null });
|
||||
}
|
||||
|
||||
if (idsToTrash.length > 0) {
|
||||
|
||||
@@ -399,7 +399,10 @@ export class IntegrityService extends BaseService {
|
||||
await this.integrityRepository.deleteByIds(outdatedReports);
|
||||
}
|
||||
|
||||
const missingFiles = results.filter(({ exists }) => !exists);
|
||||
const missingFiles = Object.values(
|
||||
Object.fromEntries(results.filter(({ exists }) => !exists).map((file) => [file.path, file])),
|
||||
);
|
||||
|
||||
if (missingFiles.length > 0) {
|
||||
await this.integrityRepository.create(
|
||||
missingFiles.map(({ path, assetId, fileAssetId }) => ({
|
||||
|
||||
@@ -512,6 +512,82 @@ describe(IntegrityService.name, () => {
|
||||
nextCursor: undefined,
|
||||
});
|
||||
});
|
||||
|
||||
it('should not fail when the same path is duplicated within a batch', async () => {
|
||||
const { sut, ctx } = setup();
|
||||
const storage = ctx.getMock(StorageRepository);
|
||||
|
||||
const {
|
||||
result: { id: ownerId },
|
||||
} = await ctx.newUser();
|
||||
|
||||
const {
|
||||
result: { id: assetId1 },
|
||||
} = await ctx.newAsset({ ownerId, originalPath: '/path/to/duplicate' });
|
||||
|
||||
const {
|
||||
result: { id: assetId2 },
|
||||
} = await ctx.newAsset({ ownerId, originalPath: '/path/to/duplicate' });
|
||||
|
||||
const fileAssetId1 = randomUUID();
|
||||
await ctx.newAssetFile({
|
||||
id: fileAssetId1,
|
||||
assetId: assetId1,
|
||||
type: AssetFileType.Thumbnail,
|
||||
path: '/path/to/duplicate-file',
|
||||
});
|
||||
|
||||
const fileAssetId2 = randomUUID();
|
||||
await ctx.newAssetFile({
|
||||
id: fileAssetId2,
|
||||
assetId: assetId1,
|
||||
type: AssetFileType.Preview,
|
||||
path: '/path/to/duplicate-file',
|
||||
});
|
||||
|
||||
const {
|
||||
result: { id: assetId3 },
|
||||
} = await ctx.newAsset({ ownerId, originalPath: '/path/to/duplicate-cross' });
|
||||
|
||||
const fileAssetId3 = randomUUID();
|
||||
await ctx.newAssetFile({
|
||||
id: fileAssetId3,
|
||||
assetId: assetId3,
|
||||
type: AssetFileType.Thumbnail,
|
||||
path: '/path/to/duplicate-cross',
|
||||
});
|
||||
|
||||
storage.stat.mockRejectedValue(new Error('ENOENT'));
|
||||
|
||||
await expect(
|
||||
sut.handleMissingFiles({
|
||||
items: [
|
||||
{ path: '/path/to/duplicate', assetId: assetId1, fileAssetId: null, reportId: null },
|
||||
{ path: '/path/to/duplicate', assetId: assetId2, fileAssetId: null, reportId: null },
|
||||
{ path: '/path/to/duplicate-file', assetId: null, fileAssetId: fileAssetId1, reportId: null },
|
||||
{ path: '/path/to/duplicate-file', assetId: null, fileAssetId: fileAssetId2, reportId: null },
|
||||
{ path: '/path/to/duplicate-cross', assetId: assetId3, fileAssetId: null, reportId: null },
|
||||
{ path: '/path/to/duplicate-cross', assetId: null, fileAssetId: fileAssetId3, reportId: null },
|
||||
],
|
||||
}),
|
||||
).resolves.toBe(JobStatus.Success);
|
||||
|
||||
await expect(
|
||||
ctx.get(IntegrityRepository).getIntegrityReport(
|
||||
{
|
||||
limit: 100,
|
||||
},
|
||||
IntegrityReport.MissingFile,
|
||||
),
|
||||
).resolves.toEqual({
|
||||
items: expect.arrayContaining([
|
||||
expect.objectContaining({ path: '/path/to/duplicate' }),
|
||||
expect.objectContaining({ path: '/path/to/duplicate-file' }),
|
||||
expect.objectContaining({ path: '/path/to/duplicate-cross' }),
|
||||
]),
|
||||
nextCursor: undefined,
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('handleMissingRefresh', () => {
|
||||
@@ -686,6 +762,40 @@ describe(IntegrityService.name, () => {
|
||||
nextCursor: undefined,
|
||||
});
|
||||
});
|
||||
|
||||
it('should not fail when the same path is duplicated across assets', async () => {
|
||||
const { sut, ctx } = setup();
|
||||
const storage = ctx.getMock(StorageRepository);
|
||||
const job = ctx.getMock(JobRepository);
|
||||
job.queue.mockResolvedValue(void 0);
|
||||
|
||||
const {
|
||||
result: { id: ownerId },
|
||||
} = await ctx.newUser();
|
||||
|
||||
await ctx.newAsset({ ownerId, originalPath: '/path/to/duplicate', checksum: Buffer.from('mismatch-a') });
|
||||
await ctx.newAsset({ ownerId, originalPath: '/path/to/duplicate', checksum: Buffer.from('mismatch-b') });
|
||||
|
||||
storage.createPlainReadStream.mockImplementation(() => Readable.from('garbage data'));
|
||||
|
||||
await expect(sut.handleChecksumFiles({ refreshOnly: false })).resolves.toBe(JobStatus.Success);
|
||||
|
||||
await expect(
|
||||
ctx.get(IntegrityRepository).getIntegrityReport(
|
||||
{
|
||||
limit: 100,
|
||||
},
|
||||
IntegrityReport.ChecksumFail,
|
||||
),
|
||||
).resolves.toEqual({
|
||||
items: [
|
||||
expect.objectContaining({
|
||||
path: '/path/to/duplicate',
|
||||
}),
|
||||
],
|
||||
nextCursor: undefined,
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('handleChecksumRefresh', () => {
|
||||
|
||||
Reference in New Issue
Block a user