@howells/stow-server 0.2.0 → 0.3.1

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/dist/index.d.mts CHANGED
@@ -21,11 +21,13 @@
21
21
  * console.log(result.url);
22
22
  * ```
23
23
  */
24
+ /** Error thrown when the Stow API returns a non-success response. */
24
25
  declare class StowError extends Error {
25
26
  readonly status: number;
26
27
  readonly code?: string;
27
28
  constructor(message: string, status: number, code?: string);
28
29
  }
30
+ /** Configuration for creating a {@link StowServer} instance. */
29
31
  interface StowServerConfig {
30
32
  apiKey: string;
31
33
  baseUrl?: string;
@@ -36,6 +38,7 @@ interface StowServerConfig {
36
38
  /** Request timeout in ms (default 30000) */
37
39
  timeout?: number;
38
40
  }
41
+ /** Response returned after an upload, confirm, or replace operation. */
39
42
  interface UploadResult {
40
43
  contentType: string;
41
44
  /** True when upload short-circuited to an existing file by content hash dedupe. */
@@ -45,6 +48,7 @@ interface UploadResult {
45
48
  size: number;
46
49
  url: string | null;
47
50
  }
51
+ /** Bucket metadata returned by bucket APIs. */
48
52
  interface BucketResult {
49
53
  allowedTypes?: string[] | null;
50
54
  createdAt?: string;
@@ -59,9 +63,11 @@ interface BucketResult {
59
63
  storageQuota?: number | null;
60
64
  usageBytes?: number;
61
65
  }
66
+ /** Result payload from `listBuckets()`. */
62
67
  interface ListBucketsResult {
63
68
  buckets: BucketResult[];
64
69
  }
70
+ /** Input payload for `createBucket()`. */
65
71
  interface CreateBucketRequest {
66
72
  allowedTypes?: string[];
67
73
  description?: string;
@@ -73,6 +79,7 @@ interface CreateBucketRequest {
73
79
  storageQuota?: number;
74
80
  webhookUrl?: string;
75
81
  }
82
+ /** Partial update payload for `updateBucket()`. */
76
83
  interface UpdateBucketRequest {
77
84
  allowedTypes?: string[] | null;
78
85
  description?: string | null;
@@ -84,6 +91,7 @@ interface UpdateBucketRequest {
84
91
  storageQuota?: number | null;
85
92
  webhookUrl?: string | null;
86
93
  }
94
+ /** Account and credential details for the active API key. */
87
95
  interface WhoamiResult {
88
96
  key?: {
89
97
  name: string;
@@ -99,16 +107,19 @@ interface WhoamiResult {
99
107
  email: string;
100
108
  };
101
109
  }
110
+ /** Query parameters for signed image transform URLs. */
102
111
  interface TransformOptions {
103
112
  format?: "webp" | "avif" | "jpeg" | "png";
104
113
  height?: number;
105
114
  quality?: number;
106
115
  width?: number;
107
116
  }
117
+ /** Paginated file listing payload. */
108
118
  interface ListFilesResult {
109
119
  files: ListFilesItem[];
110
120
  nextCursor: string | null;
111
121
  }
122
+ /** One extracted palette color for a file. */
112
123
  interface FileColor {
113
124
  hex: string;
114
125
  hsl: {
@@ -130,6 +141,7 @@ interface FileColor {
130
141
  position: number;
131
142
  proportion: number;
132
143
  }
144
+ /** Aggregated color profile metadata extracted from a file. */
133
145
  interface FileColorProfile {
134
146
  accent: {
135
147
  hex: string;
@@ -157,6 +169,7 @@ interface FileColorProfile {
157
169
  dominantFamily: string | null;
158
170
  };
159
171
  }
172
+ /** File item returned from list/search APIs. */
160
173
  interface ListFilesItem {
161
174
  colorProfile?: FileColorProfile | null;
162
175
  colors?: FileColor[];
@@ -169,6 +182,7 @@ interface ListFilesItem {
169
182
  url: string | null;
170
183
  width?: number | null;
171
184
  }
185
+ /** Result payload returned from `drop()`. */
172
186
  interface DropResult {
173
187
  contentType: string;
174
188
  filename: string;
@@ -176,6 +190,7 @@ interface DropResult {
176
190
  size: number;
177
191
  url: string;
178
192
  }
193
+ /** Drop entity returned from drop listing APIs. */
179
194
  interface Drop {
180
195
  contentType: string;
181
196
  createdAt: string;
@@ -185,6 +200,7 @@ interface Drop {
185
200
  size: number;
186
201
  url: string;
187
202
  }
203
+ /** Result payload from `listDrops()`. */
188
204
  interface ListDropsResult {
189
205
  drops: Drop[];
190
206
  usage: {
@@ -192,6 +208,7 @@ interface ListDropsResult {
192
208
  limit: number;
193
209
  };
194
210
  }
211
+ /** Full file detail payload returned by `getFile()`. */
195
212
  interface FileResult {
196
213
  colorProfile: FileColorProfile | null;
197
214
  colors: FileColor[];
@@ -206,11 +223,13 @@ interface FileResult {
206
223
  url: string | null;
207
224
  width: number | null;
208
225
  }
226
+ /** Input for creating a taste profile. */
209
227
  interface ProfileCreateRequest {
210
228
  bucket?: string;
211
229
  fileKeys?: string[];
212
230
  name?: string;
213
231
  }
232
+ /** Cluster summary within a taste profile. */
214
233
  interface ProfileClusterResult {
215
234
  description: string | null;
216
235
  id: string;
@@ -218,8 +237,20 @@ interface ProfileClusterResult {
218
237
  name: string | null;
219
238
  nameGeneratedAt: string | null;
220
239
  signalCount: number;
240
+ /**
241
+ * Optional taxonomy terms inferred for the cluster centroid.
242
+ * Absent when taxonomy data is unavailable for the bucket/profile.
243
+ */
244
+ tags?: Array<{
245
+ group: string;
246
+ groupSlug: string;
247
+ similarity: number;
248
+ tag: string;
249
+ tagSlug: string;
250
+ }>;
221
251
  totalWeight: number;
222
252
  }
253
+ /** Taste profile detail payload. */
223
254
  interface ProfileResult {
224
255
  clusters?: ProfileClusterResult[];
225
256
  createdAt: string;
@@ -230,58 +261,70 @@ interface ProfileResult {
230
261
  updatedAt: string;
231
262
  vector: number[] | null;
232
263
  }
264
+ /** Input for recomputing profile clusters. */
233
265
  interface ReclusterRequest {
234
266
  clusterCount?: number;
235
267
  }
268
+ /** Result payload from cluster recomputation. */
236
269
  interface ReclusterResult {
237
270
  clustered: boolean;
238
271
  clusters: ProfileClusterResult[];
239
272
  profileId: string;
240
273
  totalSignals: number;
241
274
  }
275
+ /** Input for updating cluster display metadata. */
242
276
  interface RenameClusterRequest {
243
277
  description?: string;
244
278
  name?: string;
245
279
  }
280
+ /** Result payload when adding/removing files from a profile. */
246
281
  interface ProfileFilesResult {
247
282
  fileCount: number;
248
283
  id: string;
249
284
  }
285
+ /** Supported signal types used to tune taste profiles. */
250
286
  type ProfileSignalType = "view" | "view_long" | "click" | "like" | "save" | "choose" | "purchase" | "share" | "dismiss" | "skip" | "reject" | "report" | "custom";
287
+ /** One signal item submitted to profile signal APIs. */
251
288
  interface ProfileSignalInput {
252
289
  context?: Record<string, unknown>;
253
290
  fileKey: string;
254
291
  type: ProfileSignalType;
255
292
  weight?: number;
256
293
  }
294
+ /** Persisted profile signal entry returned by the API. */
257
295
  interface ProfileSignalResult {
258
296
  fileKey: string;
259
297
  id: string;
260
298
  type: ProfileSignalType;
261
299
  weight: number;
262
300
  }
301
+ /** Result payload when listing or appending profile signals. */
263
302
  interface ProfileSignalsResponse {
264
303
  profileId: string;
265
304
  signals: ProfileSignalResult[];
266
305
  totalSignals: number;
267
306
  vectorUpdated: boolean;
268
307
  }
308
+ /** Result payload after removing profile signals. */
269
309
  interface DeleteProfileSignalsResult {
270
310
  profileId: string;
271
311
  removed: number;
272
312
  totalSignals: number;
273
313
  vectorUpdated: boolean;
274
314
  }
275
- interface ReprocessResult {
315
+ /** Result payload from task trigger endpoints. */
316
+ interface TaskTriggerResult {
276
317
  key: string;
277
- triggered: string[];
318
+ triggered: string;
278
319
  }
320
+ /** Result payload from replace operations. */
279
321
  interface ReplaceResult {
280
322
  contentType: string;
281
323
  key: string;
282
324
  size: number;
283
325
  triggered: string[];
284
326
  }
327
+ /** Shared structured filters for semantic search endpoints. */
285
328
  interface SearchFilters {
286
329
  color?: {
287
330
  dominantFamily?: string[];
@@ -305,7 +348,9 @@ interface SearchFilters {
305
348
  taxonomies?: string[];
306
349
  taxonomyGroups?: string[];
307
350
  }
351
+ /** Optional enrichment blocks that can be included in search responses. */
308
352
  type SearchIncludeField = "tags" | "taxonomies" | "colors" | "colorProfile";
353
+ /** Input payload for text-based semantic search. */
309
354
  interface TextSearchRequest {
310
355
  bucket?: string;
311
356
  filters?: SearchFilters;
@@ -333,6 +378,7 @@ interface PresignDedupeResult {
333
378
  }
334
379
  /** Presign response is either a new upload or a dedup hit. Check `result.dedupe` to differentiate. */
335
380
  type PresignResult = PresignNewResult | PresignDedupeResult;
381
+ /** Input payload for requesting presigned upload URLs. */
336
382
  interface PresignRequest {
337
383
  /** Override the default bucket */
338
384
  bucket?: string;
@@ -347,6 +393,7 @@ interface PresignRequest {
347
393
  /** File size in bytes */
348
394
  size: number;
349
395
  }
396
+ /** Input payload for confirming a direct upload. */
350
397
  interface ConfirmUploadRequest {
351
398
  /** Request AI-generated alt text for images */
352
399
  altText?: boolean;
@@ -355,8 +402,6 @@ interface ConfirmUploadRequest {
355
402
  /** SHA-256 hex digest of file content. Stored with the file record for future dedup lookups. */
356
403
  contentHash?: string;
357
404
  contentType: string;
358
- /** Fire KV sync in background instead of blocking. Saves ~100ms per upload. */
359
- deferKvSync?: boolean;
360
405
  /** Request AI-generated description for images */
361
406
  describe?: boolean;
362
407
  fileKey: string;
@@ -368,6 +413,7 @@ interface ConfirmUploadRequest {
368
413
  /** Request AI-generated title for images */
369
414
  title?: boolean;
370
415
  }
416
+ /** Input payload for similarity search. */
371
417
  interface SimilarSearchRequest {
372
418
  /** Bucket name or ID to scope search */
373
419
  bucket?: string;
@@ -390,6 +436,7 @@ interface SimilarSearchRequest {
390
436
  /** Search directly with a vector (1024 dimensions) */
391
437
  vector?: number[];
392
438
  }
439
+ /** Input payload for diversity-aware search. */
393
440
  interface DiverseSearchRequest {
394
441
  /** Bucket name or ID to scope search */
395
442
  bucket?: string;
@@ -414,6 +461,7 @@ interface DiverseSearchRequest {
414
461
  /** Search directly with a vector (1024 dimensions) as the relevance seed */
415
462
  vector?: number[];
416
463
  }
464
+ /** One semantic search result item. */
417
465
  interface SearchResultItem {
418
466
  bucketId: string;
419
467
  colorProfile?: FileColorProfile | null;
@@ -441,15 +489,18 @@ interface SearchResultItem {
441
489
  }>;
442
490
  width?: number | null;
443
491
  }
492
+ /** Metadata describing server-side filter pruning. */
444
493
  interface FilteredMetadata {
445
494
  candidatesScanned: number;
446
495
  requested: number;
447
496
  returned: number;
448
497
  }
498
+ /** Result payload returned by similarity/diversity search endpoints. */
449
499
  interface SimilarSearchResult {
450
500
  filtered?: FilteredMetadata;
451
501
  results: SearchResultItem[];
452
502
  }
503
+ /** Input payload for color similarity search. */
453
504
  interface ColorSearchRequest {
454
505
  /** Bucket name or ID to scope search */
455
506
  bucket?: string;
@@ -468,6 +519,7 @@ interface ColorSearchRequest {
468
519
  b: number;
469
520
  };
470
521
  }
522
+ /** One color search result item. */
471
523
  interface ColorSearchResultItem {
472
524
  bucketId: string;
473
525
  colorDistance: number;
@@ -486,9 +538,11 @@ interface ColorSearchResultItem {
486
538
  proportion: number;
487
539
  };
488
540
  }
541
+ /** Result payload for color similarity search. */
489
542
  interface ColorSearchResult {
490
543
  results: ColorSearchResultItem[];
491
544
  }
545
+ /** Server-side SDK client for Stow's API. */
492
546
  declare class StowServer {
493
547
  private readonly apiKey;
494
548
  private readonly baseUrl;
@@ -631,12 +685,19 @@ declare class StowServer {
631
685
  bucket?: string;
632
686
  }): Promise<FileResult>;
633
687
  /**
634
- * Reprocess a file: reset all derived data (embeddings, colors, dimensions,
635
- * AI metadata, taxonomies) and re-trigger processing tasks.
688
+ * Extract color palette from an image file.
689
+ * Requires a searchable bucket.
636
690
  */
637
- reprocessFile(key: string, options?: {
638
- bucket?: string;
639
- }): Promise<ReprocessResult>;
691
+ extractColors(key: string): Promise<TaskTriggerResult>;
692
+ /**
693
+ * Extract dimensions (width/height) from an image or video file.
694
+ */
695
+ extractDimensions(key: string): Promise<TaskTriggerResult>;
696
+ /**
697
+ * Generate a vector embedding for an image file.
698
+ * Requires a searchable bucket.
699
+ */
700
+ embed(key: string): Promise<TaskTriggerResult>;
640
701
  /**
641
702
  * Replace a file's content by fetching from a new URL.
642
703
  *
@@ -768,4 +829,4 @@ declare class StowServer {
768
829
  private renameProfileCluster;
769
830
  }
770
831
 
771
- export { type BucketResult, type ColorSearchRequest, type ColorSearchResult, type ColorSearchResultItem, type ConfirmUploadRequest, type CreateBucketRequest, type DeleteProfileSignalsResult, type DiverseSearchRequest, type Drop, type DropResult, type FileColor, type FileColorProfile, type FileResult, type FilteredMetadata, type ListBucketsResult, type ListDropsResult, type ListFilesItem, type ListFilesResult, type PresignDedupeResult, type PresignNewResult, type PresignRequest, type PresignResult, type ProfileClusterResult, type ProfileCreateRequest, type ProfileFilesResult, type ProfileResult, type ProfileSignalInput, type ProfileSignalResult, type ProfileSignalType, type ProfileSignalsResponse, type ReclusterRequest, type ReclusterResult, type RenameClusterRequest, type ReplaceResult, type ReprocessResult, type SearchFilters, type SearchIncludeField, type SearchResultItem, type SimilarSearchRequest, type SimilarSearchResult, StowError, StowServer, type StowServerConfig, type TextSearchRequest, type TransformOptions, type UpdateBucketRequest, type UploadResult, type WhoamiResult };
832
+ export { type BucketResult, type ColorSearchRequest, type ColorSearchResult, type ColorSearchResultItem, type ConfirmUploadRequest, type CreateBucketRequest, type DeleteProfileSignalsResult, type DiverseSearchRequest, type Drop, type DropResult, type FileColor, type FileColorProfile, type FileResult, type FilteredMetadata, type ListBucketsResult, type ListDropsResult, type ListFilesItem, type ListFilesResult, type PresignDedupeResult, type PresignNewResult, type PresignRequest, type PresignResult, type ProfileClusterResult, type ProfileCreateRequest, type ProfileFilesResult, type ProfileResult, type ProfileSignalInput, type ProfileSignalResult, type ProfileSignalType, type ProfileSignalsResponse, type ReclusterRequest, type ReclusterResult, type RenameClusterRequest, type ReplaceResult, type SearchFilters, type SearchIncludeField, type SearchResultItem, type SimilarSearchRequest, type SimilarSearchResult, StowError, StowServer, type StowServerConfig, type TaskTriggerResult, type TextSearchRequest, type TransformOptions, type UpdateBucketRequest, type UploadResult, type WhoamiResult };
package/dist/index.d.ts CHANGED
@@ -21,11 +21,13 @@
21
21
  * console.log(result.url);
22
22
  * ```
23
23
  */
24
+ /** Error thrown when the Stow API returns a non-success response. */
24
25
  declare class StowError extends Error {
25
26
  readonly status: number;
26
27
  readonly code?: string;
27
28
  constructor(message: string, status: number, code?: string);
28
29
  }
30
+ /** Configuration for creating a {@link StowServer} instance. */
29
31
  interface StowServerConfig {
30
32
  apiKey: string;
31
33
  baseUrl?: string;
@@ -36,6 +38,7 @@ interface StowServerConfig {
36
38
  /** Request timeout in ms (default 30000) */
37
39
  timeout?: number;
38
40
  }
41
+ /** Response returned after an upload, confirm, or replace operation. */
39
42
  interface UploadResult {
40
43
  contentType: string;
41
44
  /** True when upload short-circuited to an existing file by content hash dedupe. */
@@ -45,6 +48,7 @@ interface UploadResult {
45
48
  size: number;
46
49
  url: string | null;
47
50
  }
51
+ /** Bucket metadata returned by bucket APIs. */
48
52
  interface BucketResult {
49
53
  allowedTypes?: string[] | null;
50
54
  createdAt?: string;
@@ -59,9 +63,11 @@ interface BucketResult {
59
63
  storageQuota?: number | null;
60
64
  usageBytes?: number;
61
65
  }
66
+ /** Result payload from `listBuckets()`. */
62
67
  interface ListBucketsResult {
63
68
  buckets: BucketResult[];
64
69
  }
70
+ /** Input payload for `createBucket()`. */
65
71
  interface CreateBucketRequest {
66
72
  allowedTypes?: string[];
67
73
  description?: string;
@@ -73,6 +79,7 @@ interface CreateBucketRequest {
73
79
  storageQuota?: number;
74
80
  webhookUrl?: string;
75
81
  }
82
+ /** Partial update payload for `updateBucket()`. */
76
83
  interface UpdateBucketRequest {
77
84
  allowedTypes?: string[] | null;
78
85
  description?: string | null;
@@ -84,6 +91,7 @@ interface UpdateBucketRequest {
84
91
  storageQuota?: number | null;
85
92
  webhookUrl?: string | null;
86
93
  }
94
+ /** Account and credential details for the active API key. */
87
95
  interface WhoamiResult {
88
96
  key?: {
89
97
  name: string;
@@ -99,16 +107,19 @@ interface WhoamiResult {
99
107
  email: string;
100
108
  };
101
109
  }
110
+ /** Query parameters for signed image transform URLs. */
102
111
  interface TransformOptions {
103
112
  format?: "webp" | "avif" | "jpeg" | "png";
104
113
  height?: number;
105
114
  quality?: number;
106
115
  width?: number;
107
116
  }
117
+ /** Paginated file listing payload. */
108
118
  interface ListFilesResult {
109
119
  files: ListFilesItem[];
110
120
  nextCursor: string | null;
111
121
  }
122
+ /** One extracted palette color for a file. */
112
123
  interface FileColor {
113
124
  hex: string;
114
125
  hsl: {
@@ -130,6 +141,7 @@ interface FileColor {
130
141
  position: number;
131
142
  proportion: number;
132
143
  }
144
+ /** Aggregated color profile metadata extracted from a file. */
133
145
  interface FileColorProfile {
134
146
  accent: {
135
147
  hex: string;
@@ -157,6 +169,7 @@ interface FileColorProfile {
157
169
  dominantFamily: string | null;
158
170
  };
159
171
  }
172
+ /** File item returned from list/search APIs. */
160
173
  interface ListFilesItem {
161
174
  colorProfile?: FileColorProfile | null;
162
175
  colors?: FileColor[];
@@ -169,6 +182,7 @@ interface ListFilesItem {
169
182
  url: string | null;
170
183
  width?: number | null;
171
184
  }
185
+ /** Result payload returned from `drop()`. */
172
186
  interface DropResult {
173
187
  contentType: string;
174
188
  filename: string;
@@ -176,6 +190,7 @@ interface DropResult {
176
190
  size: number;
177
191
  url: string;
178
192
  }
193
+ /** Drop entity returned from drop listing APIs. */
179
194
  interface Drop {
180
195
  contentType: string;
181
196
  createdAt: string;
@@ -185,6 +200,7 @@ interface Drop {
185
200
  size: number;
186
201
  url: string;
187
202
  }
203
+ /** Result payload from `listDrops()`. */
188
204
  interface ListDropsResult {
189
205
  drops: Drop[];
190
206
  usage: {
@@ -192,6 +208,7 @@ interface ListDropsResult {
192
208
  limit: number;
193
209
  };
194
210
  }
211
+ /** Full file detail payload returned by `getFile()`. */
195
212
  interface FileResult {
196
213
  colorProfile: FileColorProfile | null;
197
214
  colors: FileColor[];
@@ -206,11 +223,13 @@ interface FileResult {
206
223
  url: string | null;
207
224
  width: number | null;
208
225
  }
226
+ /** Input for creating a taste profile. */
209
227
  interface ProfileCreateRequest {
210
228
  bucket?: string;
211
229
  fileKeys?: string[];
212
230
  name?: string;
213
231
  }
232
+ /** Cluster summary within a taste profile. */
214
233
  interface ProfileClusterResult {
215
234
  description: string | null;
216
235
  id: string;
@@ -218,8 +237,20 @@ interface ProfileClusterResult {
218
237
  name: string | null;
219
238
  nameGeneratedAt: string | null;
220
239
  signalCount: number;
240
+ /**
241
+ * Optional taxonomy terms inferred for the cluster centroid.
242
+ * Absent when taxonomy data is unavailable for the bucket/profile.
243
+ */
244
+ tags?: Array<{
245
+ group: string;
246
+ groupSlug: string;
247
+ similarity: number;
248
+ tag: string;
249
+ tagSlug: string;
250
+ }>;
221
251
  totalWeight: number;
222
252
  }
253
+ /** Taste profile detail payload. */
223
254
  interface ProfileResult {
224
255
  clusters?: ProfileClusterResult[];
225
256
  createdAt: string;
@@ -230,58 +261,70 @@ interface ProfileResult {
230
261
  updatedAt: string;
231
262
  vector: number[] | null;
232
263
  }
264
+ /** Input for recomputing profile clusters. */
233
265
  interface ReclusterRequest {
234
266
  clusterCount?: number;
235
267
  }
268
+ /** Result payload from cluster recomputation. */
236
269
  interface ReclusterResult {
237
270
  clustered: boolean;
238
271
  clusters: ProfileClusterResult[];
239
272
  profileId: string;
240
273
  totalSignals: number;
241
274
  }
275
+ /** Input for updating cluster display metadata. */
242
276
  interface RenameClusterRequest {
243
277
  description?: string;
244
278
  name?: string;
245
279
  }
280
+ /** Result payload when adding/removing files from a profile. */
246
281
  interface ProfileFilesResult {
247
282
  fileCount: number;
248
283
  id: string;
249
284
  }
285
+ /** Supported signal types used to tune taste profiles. */
250
286
  type ProfileSignalType = "view" | "view_long" | "click" | "like" | "save" | "choose" | "purchase" | "share" | "dismiss" | "skip" | "reject" | "report" | "custom";
287
+ /** One signal item submitted to profile signal APIs. */
251
288
  interface ProfileSignalInput {
252
289
  context?: Record<string, unknown>;
253
290
  fileKey: string;
254
291
  type: ProfileSignalType;
255
292
  weight?: number;
256
293
  }
294
+ /** Persisted profile signal entry returned by the API. */
257
295
  interface ProfileSignalResult {
258
296
  fileKey: string;
259
297
  id: string;
260
298
  type: ProfileSignalType;
261
299
  weight: number;
262
300
  }
301
+ /** Result payload when listing or appending profile signals. */
263
302
  interface ProfileSignalsResponse {
264
303
  profileId: string;
265
304
  signals: ProfileSignalResult[];
266
305
  totalSignals: number;
267
306
  vectorUpdated: boolean;
268
307
  }
308
+ /** Result payload after removing profile signals. */
269
309
  interface DeleteProfileSignalsResult {
270
310
  profileId: string;
271
311
  removed: number;
272
312
  totalSignals: number;
273
313
  vectorUpdated: boolean;
274
314
  }
275
- interface ReprocessResult {
315
+ /** Result payload from task trigger endpoints. */
316
+ interface TaskTriggerResult {
276
317
  key: string;
277
- triggered: string[];
318
+ triggered: string;
278
319
  }
320
+ /** Result payload from replace operations. */
279
321
  interface ReplaceResult {
280
322
  contentType: string;
281
323
  key: string;
282
324
  size: number;
283
325
  triggered: string[];
284
326
  }
327
+ /** Shared structured filters for semantic search endpoints. */
285
328
  interface SearchFilters {
286
329
  color?: {
287
330
  dominantFamily?: string[];
@@ -305,7 +348,9 @@ interface SearchFilters {
305
348
  taxonomies?: string[];
306
349
  taxonomyGroups?: string[];
307
350
  }
351
+ /** Optional enrichment blocks that can be included in search responses. */
308
352
  type SearchIncludeField = "tags" | "taxonomies" | "colors" | "colorProfile";
353
+ /** Input payload for text-based semantic search. */
309
354
  interface TextSearchRequest {
310
355
  bucket?: string;
311
356
  filters?: SearchFilters;
@@ -333,6 +378,7 @@ interface PresignDedupeResult {
333
378
  }
334
379
  /** Presign response is either a new upload or a dedup hit. Check `result.dedupe` to differentiate. */
335
380
  type PresignResult = PresignNewResult | PresignDedupeResult;
381
+ /** Input payload for requesting presigned upload URLs. */
336
382
  interface PresignRequest {
337
383
  /** Override the default bucket */
338
384
  bucket?: string;
@@ -347,6 +393,7 @@ interface PresignRequest {
347
393
  /** File size in bytes */
348
394
  size: number;
349
395
  }
396
+ /** Input payload for confirming a direct upload. */
350
397
  interface ConfirmUploadRequest {
351
398
  /** Request AI-generated alt text for images */
352
399
  altText?: boolean;
@@ -355,8 +402,6 @@ interface ConfirmUploadRequest {
355
402
  /** SHA-256 hex digest of file content. Stored with the file record for future dedup lookups. */
356
403
  contentHash?: string;
357
404
  contentType: string;
358
- /** Fire KV sync in background instead of blocking. Saves ~100ms per upload. */
359
- deferKvSync?: boolean;
360
405
  /** Request AI-generated description for images */
361
406
  describe?: boolean;
362
407
  fileKey: string;
@@ -368,6 +413,7 @@ interface ConfirmUploadRequest {
368
413
  /** Request AI-generated title for images */
369
414
  title?: boolean;
370
415
  }
416
+ /** Input payload for similarity search. */
371
417
  interface SimilarSearchRequest {
372
418
  /** Bucket name or ID to scope search */
373
419
  bucket?: string;
@@ -390,6 +436,7 @@ interface SimilarSearchRequest {
390
436
  /** Search directly with a vector (1024 dimensions) */
391
437
  vector?: number[];
392
438
  }
439
+ /** Input payload for diversity-aware search. */
393
440
  interface DiverseSearchRequest {
394
441
  /** Bucket name or ID to scope search */
395
442
  bucket?: string;
@@ -414,6 +461,7 @@ interface DiverseSearchRequest {
414
461
  /** Search directly with a vector (1024 dimensions) as the relevance seed */
415
462
  vector?: number[];
416
463
  }
464
+ /** One semantic search result item. */
417
465
  interface SearchResultItem {
418
466
  bucketId: string;
419
467
  colorProfile?: FileColorProfile | null;
@@ -441,15 +489,18 @@ interface SearchResultItem {
441
489
  }>;
442
490
  width?: number | null;
443
491
  }
492
+ /** Metadata describing server-side filter pruning. */
444
493
  interface FilteredMetadata {
445
494
  candidatesScanned: number;
446
495
  requested: number;
447
496
  returned: number;
448
497
  }
498
+ /** Result payload returned by similarity/diversity search endpoints. */
449
499
  interface SimilarSearchResult {
450
500
  filtered?: FilteredMetadata;
451
501
  results: SearchResultItem[];
452
502
  }
503
+ /** Input payload for color similarity search. */
453
504
  interface ColorSearchRequest {
454
505
  /** Bucket name or ID to scope search */
455
506
  bucket?: string;
@@ -468,6 +519,7 @@ interface ColorSearchRequest {
468
519
  b: number;
469
520
  };
470
521
  }
522
+ /** One color search result item. */
471
523
  interface ColorSearchResultItem {
472
524
  bucketId: string;
473
525
  colorDistance: number;
@@ -486,9 +538,11 @@ interface ColorSearchResultItem {
486
538
  proportion: number;
487
539
  };
488
540
  }
541
+ /** Result payload for color similarity search. */
489
542
  interface ColorSearchResult {
490
543
  results: ColorSearchResultItem[];
491
544
  }
545
+ /** Server-side SDK client for Stow's API. */
492
546
  declare class StowServer {
493
547
  private readonly apiKey;
494
548
  private readonly baseUrl;
@@ -631,12 +685,19 @@ declare class StowServer {
631
685
  bucket?: string;
632
686
  }): Promise<FileResult>;
633
687
  /**
634
- * Reprocess a file: reset all derived data (embeddings, colors, dimensions,
635
- * AI metadata, taxonomies) and re-trigger processing tasks.
688
+ * Extract color palette from an image file.
689
+ * Requires a searchable bucket.
636
690
  */
637
- reprocessFile(key: string, options?: {
638
- bucket?: string;
639
- }): Promise<ReprocessResult>;
691
+ extractColors(key: string): Promise<TaskTriggerResult>;
692
+ /**
693
+ * Extract dimensions (width/height) from an image or video file.
694
+ */
695
+ extractDimensions(key: string): Promise<TaskTriggerResult>;
696
+ /**
697
+ * Generate a vector embedding for an image file.
698
+ * Requires a searchable bucket.
699
+ */
700
+ embed(key: string): Promise<TaskTriggerResult>;
640
701
  /**
641
702
  * Replace a file's content by fetching from a new URL.
642
703
  *
@@ -768,4 +829,4 @@ declare class StowServer {
768
829
  private renameProfileCluster;
769
830
  }
770
831
 
771
- export { type BucketResult, type ColorSearchRequest, type ColorSearchResult, type ColorSearchResultItem, type ConfirmUploadRequest, type CreateBucketRequest, type DeleteProfileSignalsResult, type DiverseSearchRequest, type Drop, type DropResult, type FileColor, type FileColorProfile, type FileResult, type FilteredMetadata, type ListBucketsResult, type ListDropsResult, type ListFilesItem, type ListFilesResult, type PresignDedupeResult, type PresignNewResult, type PresignRequest, type PresignResult, type ProfileClusterResult, type ProfileCreateRequest, type ProfileFilesResult, type ProfileResult, type ProfileSignalInput, type ProfileSignalResult, type ProfileSignalType, type ProfileSignalsResponse, type ReclusterRequest, type ReclusterResult, type RenameClusterRequest, type ReplaceResult, type ReprocessResult, type SearchFilters, type SearchIncludeField, type SearchResultItem, type SimilarSearchRequest, type SimilarSearchResult, StowError, StowServer, type StowServerConfig, type TextSearchRequest, type TransformOptions, type UpdateBucketRequest, type UploadResult, type WhoamiResult };
832
+ export { type BucketResult, type ColorSearchRequest, type ColorSearchResult, type ColorSearchResultItem, type ConfirmUploadRequest, type CreateBucketRequest, type DeleteProfileSignalsResult, type DiverseSearchRequest, type Drop, type DropResult, type FileColor, type FileColorProfile, type FileResult, type FilteredMetadata, type ListBucketsResult, type ListDropsResult, type ListFilesItem, type ListFilesResult, type PresignDedupeResult, type PresignNewResult, type PresignRequest, type PresignResult, type ProfileClusterResult, type ProfileCreateRequest, type ProfileFilesResult, type ProfileResult, type ProfileSignalInput, type ProfileSignalResult, type ProfileSignalType, type ProfileSignalsResponse, type ReclusterRequest, type ReclusterResult, type RenameClusterRequest, type ReplaceResult, type SearchFilters, type SearchIncludeField, type SearchResultItem, type SimilarSearchRequest, type SimilarSearchResult, StowError, StowServer, type StowServerConfig, type TaskTriggerResult, type TextSearchRequest, type TransformOptions, type UpdateBucketRequest, type UploadResult, type WhoamiResult };
package/dist/index.js CHANGED
@@ -122,9 +122,9 @@ var listFilesSchema = import_zod.z.object({
122
122
  ),
123
123
  nextCursor: import_zod.z.string().nullable()
124
124
  });
125
- var reprocessResultSchema = import_zod.z.object({
125
+ var taskTriggerResultSchema = import_zod.z.object({
126
126
  key: import_zod.z.string(),
127
- triggered: import_zod.z.array(import_zod.z.string())
127
+ triggered: import_zod.z.string()
128
128
  });
129
129
  var replaceResultSchema = import_zod.z.object({
130
130
  key: import_zod.z.string(),
@@ -201,7 +201,16 @@ var profileClusterResultSchema = import_zod.z.object({
201
201
  description: import_zod.z.string().nullable(),
202
202
  signalCount: import_zod.z.number().int(),
203
203
  totalWeight: import_zod.z.number(),
204
- nameGeneratedAt: import_zod.z.string().nullable()
204
+ nameGeneratedAt: import_zod.z.string().nullable(),
205
+ tags: import_zod.z.array(
206
+ import_zod.z.object({
207
+ tag: import_zod.z.string(),
208
+ tagSlug: import_zod.z.string(),
209
+ group: import_zod.z.string(),
210
+ groupSlug: import_zod.z.string(),
211
+ similarity: import_zod.z.number()
212
+ })
213
+ ).optional()
205
214
  });
206
215
  var profileResultSchema = import_zod.z.object({
207
216
  id: import_zod.z.string(),
@@ -579,7 +588,6 @@ var StowServer = class {
579
588
  bucket,
580
589
  metadata,
581
590
  skipVerify,
582
- deferKvSync,
583
591
  contentHash,
584
592
  title,
585
593
  describe,
@@ -596,7 +604,6 @@ var StowServer = class {
596
604
  contentType,
597
605
  ...metadata ? { metadata } : {},
598
606
  ...skipVerify ? { skipVerify } : {},
599
- ...deferKvSync ? { deferKvSync } : {},
600
607
  ...contentHash ? { contentHash } : {},
601
608
  ...title ? { title } : {},
602
609
  ...describe ? { describe } : {},
@@ -662,15 +669,35 @@ var StowServer = class {
662
669
  );
663
670
  }
664
671
  /**
665
- * Reprocess a file: reset all derived data (embeddings, colors, dimensions,
666
- * AI metadata, taxonomies) and re-trigger processing tasks.
672
+ * Extract color palette from an image file.
673
+ * Requires a searchable bucket.
667
674
  */
668
- reprocessFile(key, options) {
669
- const path = `/api/files/${encodeURIComponent(key)}/reprocess`;
675
+ extractColors(key) {
670
676
  return this.request(
671
- this.withBucket(path, options?.bucket),
677
+ `/api/files/${encodeURIComponent(key)}/extract-colors`,
678
+ { method: "POST" },
679
+ taskTriggerResultSchema
680
+ );
681
+ }
682
+ /**
683
+ * Extract dimensions (width/height) from an image or video file.
684
+ */
685
+ extractDimensions(key) {
686
+ return this.request(
687
+ `/api/files/${encodeURIComponent(key)}/extract-dimensions`,
688
+ { method: "POST" },
689
+ taskTriggerResultSchema
690
+ );
691
+ }
692
+ /**
693
+ * Generate a vector embedding for an image file.
694
+ * Requires a searchable bucket.
695
+ */
696
+ embed(key) {
697
+ return this.request(
698
+ `/api/files/${encodeURIComponent(key)}/embed`,
672
699
  { method: "POST" },
673
- reprocessResultSchema
700
+ taskTriggerResultSchema
674
701
  );
675
702
  }
676
703
  /**
package/dist/index.mjs CHANGED
@@ -97,9 +97,9 @@ var listFilesSchema = z.object({
97
97
  ),
98
98
  nextCursor: z.string().nullable()
99
99
  });
100
- var reprocessResultSchema = z.object({
100
+ var taskTriggerResultSchema = z.object({
101
101
  key: z.string(),
102
- triggered: z.array(z.string())
102
+ triggered: z.string()
103
103
  });
104
104
  var replaceResultSchema = z.object({
105
105
  key: z.string(),
@@ -176,7 +176,16 @@ var profileClusterResultSchema = z.object({
176
176
  description: z.string().nullable(),
177
177
  signalCount: z.number().int(),
178
178
  totalWeight: z.number(),
179
- nameGeneratedAt: z.string().nullable()
179
+ nameGeneratedAt: z.string().nullable(),
180
+ tags: z.array(
181
+ z.object({
182
+ tag: z.string(),
183
+ tagSlug: z.string(),
184
+ group: z.string(),
185
+ groupSlug: z.string(),
186
+ similarity: z.number()
187
+ })
188
+ ).optional()
180
189
  });
181
190
  var profileResultSchema = z.object({
182
191
  id: z.string(),
@@ -554,7 +563,6 @@ var StowServer = class {
554
563
  bucket,
555
564
  metadata,
556
565
  skipVerify,
557
- deferKvSync,
558
566
  contentHash,
559
567
  title,
560
568
  describe,
@@ -571,7 +579,6 @@ var StowServer = class {
571
579
  contentType,
572
580
  ...metadata ? { metadata } : {},
573
581
  ...skipVerify ? { skipVerify } : {},
574
- ...deferKvSync ? { deferKvSync } : {},
575
582
  ...contentHash ? { contentHash } : {},
576
583
  ...title ? { title } : {},
577
584
  ...describe ? { describe } : {},
@@ -637,15 +644,35 @@ var StowServer = class {
637
644
  );
638
645
  }
639
646
  /**
640
- * Reprocess a file: reset all derived data (embeddings, colors, dimensions,
641
- * AI metadata, taxonomies) and re-trigger processing tasks.
647
+ * Extract color palette from an image file.
648
+ * Requires a searchable bucket.
642
649
  */
643
- reprocessFile(key, options) {
644
- const path = `/api/files/${encodeURIComponent(key)}/reprocess`;
650
+ extractColors(key) {
645
651
  return this.request(
646
- this.withBucket(path, options?.bucket),
652
+ `/api/files/${encodeURIComponent(key)}/extract-colors`,
653
+ { method: "POST" },
654
+ taskTriggerResultSchema
655
+ );
656
+ }
657
+ /**
658
+ * Extract dimensions (width/height) from an image or video file.
659
+ */
660
+ extractDimensions(key) {
661
+ return this.request(
662
+ `/api/files/${encodeURIComponent(key)}/extract-dimensions`,
663
+ { method: "POST" },
664
+ taskTriggerResultSchema
665
+ );
666
+ }
667
+ /**
668
+ * Generate a vector embedding for an image file.
669
+ * Requires a searchable bucket.
670
+ */
671
+ embed(key) {
672
+ return this.request(
673
+ `/api/files/${encodeURIComponent(key)}/embed`,
647
674
  { method: "POST" },
648
- reprocessResultSchema
675
+ taskTriggerResultSchema
649
676
  );
650
677
  }
651
678
  /**
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@howells/stow-server",
3
- "version": "0.2.0",
3
+ "version": "0.3.1",
4
4
  "description": "Server-side SDK for Stow file storage",
5
5
  "license": "MIT",
6
6
  "repository": {