@freqhole/api-client 0.3.12 → 0.3.13

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@freqhole/api-client",
3
- "version": "0.3.12",
3
+ "version": "0.3.13",
4
4
  "type": "module",
5
5
  "repository": {
6
6
  "type": "git",
@@ -132,6 +132,7 @@ export const routes = {
132
132
  enqueue_bulk_enrichment: { method: 'POST', path: '/api/music/albums/enrichment/bulk', req: s.BulkEnrichmentRequestSchema, resp: s.BulkEnrichmentResponseSchema, auth: { type: 'role', role: 'admin' } as const },
133
133
  enqueue_lastfm_album_detail: { method: 'POST', path: '/api/music/albums/lastfm/enqueue', req: s.EnqueueLastFmAlbumDetailRequestSchema, resp: s.EnqueueLastFmAlbumDetailResponseSchema, auth: { type: 'role', role: 'admin' } as const },
134
134
  enqueue_mb_album_search: { method: 'POST', path: '/api/music/albums/mb-search/enqueue', req: s.EnqueueMbAlbumSearchRequestSchema, resp: s.EnqueueMbAlbumSearchResponseSchema, auth: { type: 'role', role: 'admin' } as const },
135
+ enqueue_repair_library_images: { method: 'POST', path: '/api/music/maintenance/repair-library-images/enqueue', req: s.EnqueueRepairLibraryImagesRequestSchema, resp: s.EnqueueRepairLibraryImagesResponseSchema, auth: { type: 'role', role: 'admin' } as const },
135
136
  entity_taxons_batch: { method: 'POST', path: '/api/music/entities/taxons', req: s.EntityTaxonsBatchRequestSchema, resp: s.EntityTaxonsBatchResponseSchema, auth: { type: 'authenticated' } as const },
136
137
  era_albums: { method: 'POST', path: '/api/music/relations/era-albums', req: s.EraAlbumsRequestSchema, resp: s.EraAlbumsResponseSchema, auth: { type: 'authenticated' } as const },
137
138
  era_bins: { method: 'POST', path: '/api/music/relations/era-bins', req: s.EraBinsRequestSchema, resp: s.EraBinsResponseSchema, auth: { type: 'authenticated' } as const },
@@ -222,7 +223,7 @@ export const routes = {
222
223
  sync_job_notify: { method: 'POST', path: '/api/sync/job-notify', req: s.SyncJobNotifySchema, resp: z.boolean(), auth: { type: 'public' } as const },
223
224
  sync_playlist: { method: 'POST', path: '/api/sync/playlist', req: s.SyncPlaylistRequestSchema, resp: s.SyncPlaylistResponseSchema, auth: { type: 'role', role: 'member' } as const },
224
225
  sync_song_by_blake3: { method: 'POST', path: '/api/sync/song-by-blake3', req: s.SyncSongByBlake3RequestSchema, resp: s.SyncJobQueuedResponseSchema, auth: { type: 'role', role: 'member' } as const },
225
- synced_sha256s: { method: 'GET', path: '/api/sync/sha256s', req: null, resp: z.string().array(), auth: { type: 'role', role: 'member' } as const },
226
+ synced_blake3s: { method: 'GET', path: '/api/sync/blake3s', req: null, resp: z.string().array(), auth: { type: 'role', role: 'member' } as const },
226
227
  top_albums: { method: 'POST', path: '/api/analytics/top-albums', req: s.TopAlbumsRequestSchema, resp: s.TopAlbumSchema.array(), auth: { type: 'authenticated' } as const },
227
228
  top_artists: { method: 'POST', path: '/api/analytics/top-artists', req: s.TopArtistsRequestSchema, resp: s.TopArtistSchema.array(), auth: { type: 'authenticated' } as const },
228
229
  top_songs: { method: 'POST', path: '/api/analytics/top-songs', req: s.TopSongsRequestSchema, resp: s.TopSongSchema.array(), auth: { type: 'authenticated' } as const },
@@ -1336,7 +1336,6 @@ export type BioSource = z.infer<typeof BioSourceSchema>;
1336
1336
 
1337
1337
  export const BlobMetadataResponseSchema = z.object({
1338
1338
  id: z.string(),
1339
- sha256: z.string(),
1340
1339
  size: z.number().nullish(),
1341
1340
  mime: z.string().nullish(),
1342
1341
  filename: z.string().nullish(),
@@ -1462,7 +1461,7 @@ export const CreateArtistRequestSchema = z.object({
1462
1461
  export type CreateArtistRequest = z.infer<typeof CreateArtistRequestSchema>;
1463
1462
 
1464
1463
  export const CreateJobRequestSchema = z.object({
1465
- job_type: z.union([z.literal('ScanDirectory'), z.literal('RescanDirectories'), z.literal('ProcessFile'), z.literal('ProcessDirectory'), z.literal('FetchMedia'), z.literal('PreCheckFetch'), z.literal('ConvertWebp'), z.literal('ImportMusic'), z.literal('ImportVideo'), z.literal('TranscodeVideo'), z.literal('MbAlbumSearch'), z.literal('MbAlbumDetail'), z.literal('LastFmAlbumDetail'), z.literal('LastFmArtistDetail'), z.literal('AudioDbAlbumDetail'), z.literal('AudioDbArtistDetail'), z.literal('AlbumEnrichmentPipeline'), z.literal('AutoApplyAlbumEnrichment'), z.literal('SyncSongByBlake3'), z.literal('SyncVideoByBlake3')]),
1464
+ job_type: z.union([z.literal('ScanDirectory'), z.literal('RescanDirectories'), z.literal('ProcessFile'), z.literal('ProcessDirectory'), z.literal('FetchMedia'), z.literal('PreCheckFetch'), z.literal('ConvertWebp'), z.literal('ImportMusic'), z.literal('ImportVideo'), z.literal('TranscodeVideo'), z.literal('MbAlbumSearch'), z.literal('MbAlbumDetail'), z.literal('LastFmAlbumDetail'), z.literal('LastFmArtistDetail'), z.literal('AudioDbAlbumDetail'), z.literal('AudioDbArtistDetail'), z.literal('AlbumEnrichmentPipeline'), z.literal('AutoApplyAlbumEnrichment'), z.literal('SyncSongByBlake3'), z.literal('SyncVideoByBlake3'), z.literal('RepairLibraryImages')]),
1466
1465
  session_id: z.string().nullish(),
1467
1466
  parameters: z.any(),
1468
1467
  max_retries: z.number().nullish(),
@@ -1716,6 +1715,23 @@ export const EnqueueMbAlbumSearchResponseSchema = z.object({
1716
1715
  });
1717
1716
  export type EnqueueMbAlbumSearchResponse = z.infer<typeof EnqueueMbAlbumSearchResponseSchema>;
1718
1717
 
1718
+ export const EnqueueRepairLibraryImagesRequestSchema = z.object({
1719
+ dry_run: z.boolean(),
1720
+ scan_directory: z.string().nullish(),
1721
+ options: z.object({
1722
+ backfill_waveforms: z.boolean(),
1723
+ backfill_embedded_art: z.boolean(),
1724
+ backfill_directory_art: z.boolean(),
1725
+ remove_overapplied: z.boolean()
1726
+ })
1727
+ });
1728
+ export type EnqueueRepairLibraryImagesRequest = z.infer<typeof EnqueueRepairLibraryImagesRequestSchema>;
1729
+
1730
+ export const EnqueueRepairLibraryImagesResponseSchema = z.object({
1731
+ job_id: z.string()
1732
+ });
1733
+ export type EnqueueRepairLibraryImagesResponse = z.infer<typeof EnqueueRepairLibraryImagesResponseSchema>;
1734
+
1719
1735
  export const EnrichmentLogEntrySchema = z.object({
1720
1736
  at: z.number(),
1721
1737
  step: z.string(),
@@ -1927,7 +1943,7 @@ export const ErrorDetailSchema = z.object({
1927
1943
  export type ErrorDetail = z.infer<typeof ErrorDetailSchema>;
1928
1944
 
1929
1945
  export const EventFilterSchema = z.object({
1930
- kinds: z.array(z.union([z.literal('ScanDirectory'), z.literal('RescanDirectories'), z.literal('ProcessFile'), z.literal('ProcessDirectory'), z.literal('FetchMedia'), z.literal('PreCheckFetch'), z.literal('ConvertWebp'), z.literal('ImportMusic'), z.literal('ImportVideo'), z.literal('TranscodeVideo'), z.literal('MbAlbumSearch'), z.literal('MbAlbumDetail'), z.literal('LastFmAlbumDetail'), z.literal('LastFmArtistDetail'), z.literal('AudioDbAlbumDetail'), z.literal('AudioDbArtistDetail'), z.literal('AlbumEnrichmentPipeline'), z.literal('AutoApplyAlbumEnrichment'), z.literal('SyncSongByBlake3'), z.literal('SyncVideoByBlake3')])).nullish(),
1946
+ kinds: z.array(z.union([z.literal('ScanDirectory'), z.literal('RescanDirectories'), z.literal('ProcessFile'), z.literal('ProcessDirectory'), z.literal('FetchMedia'), z.literal('PreCheckFetch'), z.literal('ConvertWebp'), z.literal('ImportMusic'), z.literal('ImportVideo'), z.literal('TranscodeVideo'), z.literal('MbAlbumSearch'), z.literal('MbAlbumDetail'), z.literal('LastFmAlbumDetail'), z.literal('LastFmArtistDetail'), z.literal('AudioDbAlbumDetail'), z.literal('AudioDbArtistDetail'), z.literal('AlbumEnrichmentPipeline'), z.literal('AutoApplyAlbumEnrichment'), z.literal('SyncSongByBlake3'), z.literal('SyncVideoByBlake3'), z.literal('RepairLibraryImages')])).nullish(),
1931
1947
  job_ids: z.array(z.string()).nullish(),
1932
1948
  session_ids: z.array(z.string()).nullish(),
1933
1949
  entity_refs: z.array(z.union([z.object({
@@ -2190,7 +2206,6 @@ export const FavoriteItemSchema = z.union([z.intersection(z.object({
2190
2206
  }).nullish(),
2191
2207
  media_blob: z.object({
2192
2208
  id: z.string(),
2193
- sha256: z.string(),
2194
2209
  size: z.number().nullish(),
2195
2210
  mime: z.string().nullish(),
2196
2211
  source_client_id: z.string().nullish(),
@@ -2582,7 +2597,6 @@ export const FavoriteSongResultSchema = z.object({
2582
2597
  }).nullish(),
2583
2598
  media_blob: z.object({
2584
2599
  id: z.string(),
2585
- sha256: z.string(),
2586
2600
  size: z.number().nullish(),
2587
2601
  mime: z.string().nullish(),
2588
2602
  source_client_id: z.string().nullish(),
@@ -3093,16 +3107,13 @@ export const GetVideoSeriesRequestSchema = z.object({
3093
3107
  export type GetVideoSeriesRequest = z.infer<typeof GetVideoSeriesRequestSchema>;
3094
3108
 
3095
3109
  export const HasBlobsRequestSchema = z.object({
3096
- blake3s: z.array(z.string()),
3097
- sha256s: z.array(z.string())
3110
+ blake3s: z.array(z.string())
3098
3111
  });
3099
3112
  export type HasBlobsRequest = z.infer<typeof HasBlobsRequestSchema>;
3100
3113
 
3101
3114
  export const HasBlobsResponseSchema = z.object({
3102
3115
  blake3s_present: z.array(z.string()),
3103
- blake3s_missing: z.array(z.string()),
3104
- sha256s_present: z.array(z.string()),
3105
- sha256s_missing: z.array(z.string())
3116
+ blake3s_missing: z.array(z.string())
3106
3117
  });
3107
3118
  export type HasBlobsResponse = z.infer<typeof HasBlobsResponseSchema>;
3108
3119
 
@@ -3131,7 +3142,7 @@ export type ImageMetadata = z.infer<typeof ImageMetadataSchema>;
3131
3142
  export const ImageUploadResponseSchema = z.object({
3132
3143
  blob_id: z.string(),
3133
3144
  job_id: z.string(),
3134
- sha256: z.string(),
3145
+ blake3: z.string(),
3135
3146
  size: z.number(),
3136
3147
  mime: z.string(),
3137
3148
  existing: z.boolean(),
@@ -3170,7 +3181,7 @@ export type IngestRemoteImageRequest = z.infer<typeof IngestRemoteImageRequestSc
3170
3181
 
3171
3182
  export const IngestRemoteImageResponseSchema = z.object({
3172
3183
  blob_id: z.string(),
3173
- sha256: z.string(),
3184
+ blake3: z.string(),
3174
3185
  size: z.number(),
3175
3186
  mime: z.string(),
3176
3187
  deduped: z.boolean()
@@ -3182,7 +3193,7 @@ export const JobEventSchema = z.union([z.object({
3182
3193
  session_id: z.string(),
3183
3194
  complete: z.number(),
3184
3195
  total: z.number(),
3185
- topic: z.union([z.literal('ScanDirectory'), z.literal('RescanDirectories'), z.literal('ProcessFile'), z.literal('ProcessDirectory'), z.literal('FetchMedia'), z.literal('PreCheckFetch'), z.literal('ConvertWebp'), z.literal('ImportMusic'), z.literal('ImportVideo'), z.literal('TranscodeVideo'), z.literal('MbAlbumSearch'), z.literal('MbAlbumDetail'), z.literal('LastFmAlbumDetail'), z.literal('LastFmArtistDetail'), z.literal('AudioDbAlbumDetail'), z.literal('AudioDbArtistDetail'), z.literal('AlbumEnrichmentPipeline'), z.literal('AutoApplyAlbumEnrichment'), z.literal('SyncSongByBlake3'), z.literal('SyncVideoByBlake3')]),
3196
+ topic: z.union([z.literal('ScanDirectory'), z.literal('RescanDirectories'), z.literal('ProcessFile'), z.literal('ProcessDirectory'), z.literal('FetchMedia'), z.literal('PreCheckFetch'), z.literal('ConvertWebp'), z.literal('ImportMusic'), z.literal('ImportVideo'), z.literal('TranscodeVideo'), z.literal('MbAlbumSearch'), z.literal('MbAlbumDetail'), z.literal('LastFmAlbumDetail'), z.literal('LastFmArtistDetail'), z.literal('AudioDbAlbumDetail'), z.literal('AudioDbArtistDetail'), z.literal('AlbumEnrichmentPipeline'), z.literal('AutoApplyAlbumEnrichment'), z.literal('SyncSongByBlake3'), z.literal('SyncVideoByBlake3'), z.literal('RepairLibraryImages')]),
3186
3197
  entity_ref: z.union([z.object({
3187
3198
  kind: z.literal('album'),
3188
3199
  id: z.string()
@@ -3198,7 +3209,7 @@ export const JobEventSchema = z.union([z.object({
3198
3209
  job_id: z.string(),
3199
3210
  from: z.union([z.literal('pending'), z.literal('running'), z.literal('completed'), z.literal('failed'), z.literal('cancelled')]).nullish(),
3200
3211
  to: z.union([z.literal('pending'), z.literal('running'), z.literal('completed'), z.literal('failed'), z.literal('cancelled')]),
3201
- topic: z.union([z.literal('ScanDirectory'), z.literal('RescanDirectories'), z.literal('ProcessFile'), z.literal('ProcessDirectory'), z.literal('FetchMedia'), z.literal('PreCheckFetch'), z.literal('ConvertWebp'), z.literal('ImportMusic'), z.literal('ImportVideo'), z.literal('TranscodeVideo'), z.literal('MbAlbumSearch'), z.literal('MbAlbumDetail'), z.literal('LastFmAlbumDetail'), z.literal('LastFmArtistDetail'), z.literal('AudioDbAlbumDetail'), z.literal('AudioDbArtistDetail'), z.literal('AlbumEnrichmentPipeline'), z.literal('AutoApplyAlbumEnrichment'), z.literal('SyncSongByBlake3'), z.literal('SyncVideoByBlake3')]),
3212
+ topic: z.union([z.literal('ScanDirectory'), z.literal('RescanDirectories'), z.literal('ProcessFile'), z.literal('ProcessDirectory'), z.literal('FetchMedia'), z.literal('PreCheckFetch'), z.literal('ConvertWebp'), z.literal('ImportMusic'), z.literal('ImportVideo'), z.literal('TranscodeVideo'), z.literal('MbAlbumSearch'), z.literal('MbAlbumDetail'), z.literal('LastFmAlbumDetail'), z.literal('LastFmArtistDetail'), z.literal('AudioDbAlbumDetail'), z.literal('AudioDbArtistDetail'), z.literal('AlbumEnrichmentPipeline'), z.literal('AutoApplyAlbumEnrichment'), z.literal('SyncSongByBlake3'), z.literal('SyncVideoByBlake3'), z.literal('RepairLibraryImages')]),
3202
3213
  entity_ref: z.union([z.object({
3203
3214
  kind: z.literal('album'),
3204
3215
  id: z.string()
@@ -3213,7 +3224,7 @@ export const JobEventSchema = z.union([z.object({
3213
3224
  job_id: z.string(),
3214
3225
  error_type: z.string(),
3215
3226
  message: z.string(),
3216
- topic: z.union([z.literal('ScanDirectory'), z.literal('RescanDirectories'), z.literal('ProcessFile'), z.literal('ProcessDirectory'), z.literal('FetchMedia'), z.literal('PreCheckFetch'), z.literal('ConvertWebp'), z.literal('ImportMusic'), z.literal('ImportVideo'), z.literal('TranscodeVideo'), z.literal('MbAlbumSearch'), z.literal('MbAlbumDetail'), z.literal('LastFmAlbumDetail'), z.literal('LastFmArtistDetail'), z.literal('AudioDbAlbumDetail'), z.literal('AudioDbArtistDetail'), z.literal('AlbumEnrichmentPipeline'), z.literal('AutoApplyAlbumEnrichment'), z.literal('SyncSongByBlake3'), z.literal('SyncVideoByBlake3')]),
3227
+ topic: z.union([z.literal('ScanDirectory'), z.literal('RescanDirectories'), z.literal('ProcessFile'), z.literal('ProcessDirectory'), z.literal('FetchMedia'), z.literal('PreCheckFetch'), z.literal('ConvertWebp'), z.literal('ImportMusic'), z.literal('ImportVideo'), z.literal('TranscodeVideo'), z.literal('MbAlbumSearch'), z.literal('MbAlbumDetail'), z.literal('LastFmAlbumDetail'), z.literal('LastFmArtistDetail'), z.literal('AudioDbAlbumDetail'), z.literal('AudioDbArtistDetail'), z.literal('AlbumEnrichmentPipeline'), z.literal('AutoApplyAlbumEnrichment'), z.literal('SyncSongByBlake3'), z.literal('SyncVideoByBlake3'), z.literal('RepairLibraryImages')]),
3217
3228
  entity_ref: z.union([z.object({
3218
3229
  kind: z.literal('album'),
3219
3230
  id: z.string()
@@ -3228,7 +3239,7 @@ export const JobEventSchema = z.union([z.object({
3228
3239
  job_id: z.string(),
3229
3240
  stage: z.string(),
3230
3241
  message: z.string().nullish(),
3231
- topic: z.union([z.literal('ScanDirectory'), z.literal('RescanDirectories'), z.literal('ProcessFile'), z.literal('ProcessDirectory'), z.literal('FetchMedia'), z.literal('PreCheckFetch'), z.literal('ConvertWebp'), z.literal('ImportMusic'), z.literal('ImportVideo'), z.literal('TranscodeVideo'), z.literal('MbAlbumSearch'), z.literal('MbAlbumDetail'), z.literal('LastFmAlbumDetail'), z.literal('LastFmArtistDetail'), z.literal('AudioDbAlbumDetail'), z.literal('AudioDbArtistDetail'), z.literal('AlbumEnrichmentPipeline'), z.literal('AutoApplyAlbumEnrichment'), z.literal('SyncSongByBlake3'), z.literal('SyncVideoByBlake3')]),
3242
+ topic: z.union([z.literal('ScanDirectory'), z.literal('RescanDirectories'), z.literal('ProcessFile'), z.literal('ProcessDirectory'), z.literal('FetchMedia'), z.literal('PreCheckFetch'), z.literal('ConvertWebp'), z.literal('ImportMusic'), z.literal('ImportVideo'), z.literal('TranscodeVideo'), z.literal('MbAlbumSearch'), z.literal('MbAlbumDetail'), z.literal('LastFmAlbumDetail'), z.literal('LastFmArtistDetail'), z.literal('AudioDbAlbumDetail'), z.literal('AudioDbArtistDetail'), z.literal('AlbumEnrichmentPipeline'), z.literal('AutoApplyAlbumEnrichment'), z.literal('SyncSongByBlake3'), z.literal('SyncVideoByBlake3'), z.literal('RepairLibraryImages')]),
3232
3243
  entity_ref: z.union([z.object({
3233
3244
  kind: z.literal('album'),
3234
3245
  id: z.string()
@@ -3241,7 +3252,7 @@ export const JobEventSchema = z.union([z.object({
3241
3252
  }), z.object({
3242
3253
  kind: z.literal('completed'),
3243
3254
  session_id: z.string(),
3244
- topic: z.union([z.literal('ScanDirectory'), z.literal('RescanDirectories'), z.literal('ProcessFile'), z.literal('ProcessDirectory'), z.literal('FetchMedia'), z.literal('PreCheckFetch'), z.literal('ConvertWebp'), z.literal('ImportMusic'), z.literal('ImportVideo'), z.literal('TranscodeVideo'), z.literal('MbAlbumSearch'), z.literal('MbAlbumDetail'), z.literal('LastFmAlbumDetail'), z.literal('LastFmArtistDetail'), z.literal('AudioDbAlbumDetail'), z.literal('AudioDbArtistDetail'), z.literal('AlbumEnrichmentPipeline'), z.literal('AutoApplyAlbumEnrichment'), z.literal('SyncSongByBlake3'), z.literal('SyncVideoByBlake3')]),
3255
+ topic: z.union([z.literal('ScanDirectory'), z.literal('RescanDirectories'), z.literal('ProcessFile'), z.literal('ProcessDirectory'), z.literal('FetchMedia'), z.literal('PreCheckFetch'), z.literal('ConvertWebp'), z.literal('ImportMusic'), z.literal('ImportVideo'), z.literal('TranscodeVideo'), z.literal('MbAlbumSearch'), z.literal('MbAlbumDetail'), z.literal('LastFmAlbumDetail'), z.literal('LastFmArtistDetail'), z.literal('AudioDbAlbumDetail'), z.literal('AudioDbArtistDetail'), z.literal('AlbumEnrichmentPipeline'), z.literal('AutoApplyAlbumEnrichment'), z.literal('SyncSongByBlake3'), z.literal('SyncVideoByBlake3'), z.literal('RepairLibraryImages')]),
3245
3256
  entity_ref: z.union([z.object({
3246
3257
  kind: z.literal('album'),
3247
3258
  id: z.string()
@@ -3279,7 +3290,7 @@ export type JobResponse = z.infer<typeof JobResponseSchema>;
3279
3290
  export const JobStateSnapshotSchema = z.object({
3280
3291
  job_id: z.string(),
3281
3292
  session_id: z.string().nullish(),
3282
- job_type: z.union([z.literal('ScanDirectory'), z.literal('RescanDirectories'), z.literal('ProcessFile'), z.literal('ProcessDirectory'), z.literal('FetchMedia'), z.literal('PreCheckFetch'), z.literal('ConvertWebp'), z.literal('ImportMusic'), z.literal('ImportVideo'), z.literal('TranscodeVideo'), z.literal('MbAlbumSearch'), z.literal('MbAlbumDetail'), z.literal('LastFmAlbumDetail'), z.literal('LastFmArtistDetail'), z.literal('AudioDbAlbumDetail'), z.literal('AudioDbArtistDetail'), z.literal('AlbumEnrichmentPipeline'), z.literal('AutoApplyAlbumEnrichment'), z.literal('SyncSongByBlake3'), z.literal('SyncVideoByBlake3')]),
3293
+ job_type: z.union([z.literal('ScanDirectory'), z.literal('RescanDirectories'), z.literal('ProcessFile'), z.literal('ProcessDirectory'), z.literal('FetchMedia'), z.literal('PreCheckFetch'), z.literal('ConvertWebp'), z.literal('ImportMusic'), z.literal('ImportVideo'), z.literal('TranscodeVideo'), z.literal('MbAlbumSearch'), z.literal('MbAlbumDetail'), z.literal('LastFmAlbumDetail'), z.literal('LastFmArtistDetail'), z.literal('AudioDbAlbumDetail'), z.literal('AudioDbArtistDetail'), z.literal('AlbumEnrichmentPipeline'), z.literal('AutoApplyAlbumEnrichment'), z.literal('SyncSongByBlake3'), z.literal('SyncVideoByBlake3'), z.literal('RepairLibraryImages')]),
3283
3294
  status: z.union([z.literal('pending'), z.literal('running'), z.literal('completed'), z.literal('failed'), z.literal('cancelled')]),
3284
3295
  entity_ref: z.union([z.object({
3285
3296
  kind: z.literal('album'),
@@ -3508,7 +3519,6 @@ export const ListFavoritesResponseSchema = z.object({
3508
3519
  }).nullish(),
3509
3520
  media_blob: z.object({
3510
3521
  id: z.string(),
3511
- sha256: z.string(),
3512
3522
  size: z.number().nullish(),
3513
3523
  mime: z.string().nullish(),
3514
3524
  source_client_id: z.string().nullish(),
@@ -4307,7 +4317,6 @@ export type MbUrl = z.infer<typeof MbUrlSchema>;
4307
4317
 
4308
4318
  export const MediaBlobSchema = z.object({
4309
4319
  id: z.string(),
4310
- sha256: z.string(),
4311
4320
  size: z.number().nullish(),
4312
4321
  mime: z.string().nullish(),
4313
4322
  source_client_id: z.string().nullish(),
@@ -4451,7 +4460,7 @@ export type MusicMetadataHints = z.infer<typeof MusicMetadataHintsSchema>;
4451
4460
  export const MusicUploadResponseSchema = z.object({
4452
4461
  blob_id: z.string(),
4453
4462
  job_id: z.string(),
4454
- sha256: z.string(),
4463
+ blake3: z.string(),
4455
4464
  size: z.number(),
4456
4465
  mime: z.string(),
4457
4466
  existing: z.boolean(),
@@ -4894,7 +4903,6 @@ export const PlaylistSongResultSchema = z.object({
4894
4903
  }).nullish(),
4895
4904
  media_blob: z.object({
4896
4905
  id: z.string(),
4897
- sha256: z.string(),
4898
4906
  size: z.number().nullish(),
4899
4907
  mime: z.string().nullish(),
4900
4908
  source_client_id: z.string().nullish(),
@@ -5037,7 +5045,6 @@ export const PlaylistSongsQueryResultSchema = z.object({
5037
5045
  }).nullish(),
5038
5046
  media_blob: z.object({
5039
5047
  id: z.string(),
5040
- sha256: z.string(),
5041
5048
  size: z.number().nullish(),
5042
5049
  mime: z.string().nullish(),
5043
5050
  source_client_id: z.string().nullish(),
@@ -6038,6 +6045,47 @@ export const ReorderPlaylistSongsRequestSchema = z.object({
6038
6045
  });
6039
6046
  export type ReorderPlaylistSongsRequest = z.infer<typeof ReorderPlaylistSongsRequestSchema>;
6040
6047
 
6048
+ export const RepairLibraryImagesJobResultSchema = z.object({
6049
+ totals: z.object({
6050
+ songs_waveforms_backfilled: z.number(),
6051
+ albums_thumbnails_backfilled: z.number(),
6052
+ albums_thumbnails_removed_overapplied: z.number(),
6053
+ albums_left_ambiguous: z.number(),
6054
+ errors: z.array(z.object({
6055
+ error_type: z.string(),
6056
+ title: z.string(),
6057
+ detail: z.string()
6058
+ }))
6059
+ }),
6060
+ done: z.boolean(),
6061
+ next_job_id: z.string().nullish()
6062
+ });
6063
+ export type RepairLibraryImagesJobResult = z.infer<typeof RepairLibraryImagesJobResultSchema>;
6064
+
6065
+ export const RepairLibraryImagesOptionsSchema = z.object({
6066
+ backfill_waveforms: z.boolean(),
6067
+ backfill_embedded_art: z.boolean(),
6068
+ backfill_directory_art: z.boolean(),
6069
+ remove_overapplied: z.boolean()
6070
+ });
6071
+ export type RepairLibraryImagesOptions = z.infer<typeof RepairLibraryImagesOptionsSchema>;
6072
+
6073
+ export const RepairLibraryImagesPhaseSchema = z.union([z.literal('Waveforms'), z.literal('Directories')]);
6074
+ export type RepairLibraryImagesPhase = z.infer<typeof RepairLibraryImagesPhaseSchema>;
6075
+
6076
+ export const RepairLibraryImagesResultSchema = z.object({
6077
+ songs_waveforms_backfilled: z.number(),
6078
+ albums_thumbnails_backfilled: z.number(),
6079
+ albums_thumbnails_removed_overapplied: z.number(),
6080
+ albums_left_ambiguous: z.number(),
6081
+ errors: z.array(z.object({
6082
+ error_type: z.string(),
6083
+ title: z.string(),
6084
+ detail: z.string()
6085
+ }))
6086
+ });
6087
+ export type RepairLibraryImagesResult = z.infer<typeof RepairLibraryImagesResultSchema>;
6088
+
6041
6089
  export const ReplaceAlbumsTagsRequestSchema = z.object({
6042
6090
  album_ids: z.array(z.string()),
6043
6091
  tag_ids: z.array(z.string())
@@ -6697,7 +6745,6 @@ export const SongQueryResultSchema = z.object({
6697
6745
  }).nullish(),
6698
6746
  media_blob: z.object({
6699
6747
  id: z.string(),
6700
- sha256: z.string(),
6701
6748
  size: z.number().nullish(),
6702
6749
  mime: z.string().nullish(),
6703
6750
  source_client_id: z.string().nullish(),
@@ -6867,7 +6914,6 @@ export const SongsQueryResultSchema = z.object({
6867
6914
  }).nullish(),
6868
6915
  media_blob: z.object({
6869
6916
  id: z.string(),
6870
- sha256: z.string(),
6871
6917
  size: z.number().nullish(),
6872
6918
  mime: z.string().nullish(),
6873
6919
  source_client_id: z.string().nullish(),
@@ -7090,7 +7136,6 @@ export type SyncPlaylistResponse = z.infer<typeof SyncPlaylistResponseSchema>;
7090
7136
 
7091
7137
  export const SyncSongByBlake3RequestSchema = z.object({
7092
7138
  blake3: z.string(),
7093
- sha256: z.string(),
7094
7139
  node_id: z.string().nullish(),
7095
7140
  size: z.number().nullish(),
7096
7141
  filename: z.string(),
@@ -7130,7 +7175,6 @@ export const SyncSongByBlake3ResponseSchema = z.object({
7130
7175
  media_blob_id: z.string(),
7131
7176
  artist_id: z.string(),
7132
7177
  file_path: z.string(),
7133
- sha256: z.string(),
7134
7178
  blake3: z.string(),
7135
7179
  existing: z.boolean(),
7136
7180
  images_linked: z.number(),
@@ -7141,7 +7185,6 @@ export type SyncSongByBlake3Response = z.infer<typeof SyncSongByBlake3ResponseSc
7141
7185
  export const SyncVideoByBlake3RequestSchema = z.object({
7142
7186
  blake3: z.string(),
7143
7187
  node_id: z.string().nullish(),
7144
- sha256: z.string().nullish(),
7145
7188
  size: z.number().nullish(),
7146
7189
  filename: z.string(),
7147
7190
  source_node_id: z.string(),
@@ -8089,7 +8132,7 @@ export type VideoSeriesSearchResult = z.infer<typeof VideoSeriesSearchResultSche
8089
8132
  export const VideoUploadResponseSchema = z.object({
8090
8133
  blob_id: z.string(),
8091
8134
  job_id: z.string(),
8092
- sha256: z.string(),
8135
+ blake3: z.string(),
8093
8136
  size: z.number(),
8094
8137
  mime: z.string(),
8095
8138
  existing: z.boolean(),
@@ -1460,6 +1460,22 @@ export function createMusicMethods(call: CallFn) {
1460
1460
  );
1461
1461
  },
1462
1462
 
1463
+ // enqueue a whole-library image repair job (admin only): backfills
1464
+ // missing song waveforms / album thumbnails, and cleans up
1465
+ // directory-sourced images that got over-applied across unrelated
1466
+ // albums. returns the job id so the caller can poll status.
1467
+ enqueueRepairLibraryImages: (params: s.EnqueueRepairLibraryImagesRequest) => {
1468
+ return call(
1469
+ "music",
1470
+ "enqueue_repair_library_images",
1471
+ routes.music.enqueue_repair_library_images.resp,
1472
+ routes.music.enqueue_repair_library_images.req,
1473
+ routes.music.enqueue_repair_library_images.method,
1474
+ routes.music.enqueue_repair_library_images.path,
1475
+ params,
1476
+ );
1477
+ },
1478
+
1463
1479
  // download a remote image url and link it to an album or artist
1464
1480
  // (phase 14.6). dedups by sha256.
1465
1481
  ingestRemoteImage: (params: s.IngestRemoteImageRequest) => {
@@ -1779,15 +1795,15 @@ export function createMusicMethods(call: CallFn) {
1779
1795
  );
1780
1796
  },
1781
1797
 
1782
- // get the list of sha256 hashes known to this server for sync checks
1783
- syncedSha256s: () => {
1798
+ // get the list of blake3 hashes known to this server for sync checks
1799
+ syncedBlake3s: () => {
1784
1800
  return call(
1785
1801
  "music",
1786
- "synced_sha256s",
1787
- routes.music.synced_sha256s.resp,
1788
- routes.music.synced_sha256s.req,
1789
- routes.music.synced_sha256s.method,
1790
- routes.music.synced_sha256s.path,
1802
+ "synced_blake3s",
1803
+ routes.music.synced_blake3s.resp,
1804
+ routes.music.synced_blake3s.req,
1805
+ routes.music.synced_blake3s.method,
1806
+ routes.music.synced_blake3s.path,
1791
1807
  undefined,
1792
1808
  );
1793
1809
  },