@howells/stow-server 0.3.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/LICENSE +21 -0
- package/dist/index.d.mts +56 -2
- package/dist/index.d.ts +56 -2
- package/dist/index.js +10 -3
- package/dist/index.mjs +10 -3
- package/package.json +10 -10
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025 Stow
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
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
|
}
|
|
315
|
+
/** Result payload from task trigger endpoints. */
|
|
275
316
|
interface TaskTriggerResult {
|
|
276
317
|
key: string;
|
|
277
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;
|
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
|
}
|
|
315
|
+
/** Result payload from task trigger endpoints. */
|
|
275
316
|
interface TaskTriggerResult {
|
|
276
317
|
key: string;
|
|
277
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;
|
package/dist/index.js
CHANGED
|
@@ -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 } : {},
|
package/dist/index.mjs
CHANGED
|
@@ -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 } : {},
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@howells/stow-server",
|
|
3
|
-
"version": "0.3.
|
|
3
|
+
"version": "0.3.1",
|
|
4
4
|
"description": "Server-side SDK for Stow file storage",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"repository": {
|
|
@@ -29,21 +29,21 @@
|
|
|
29
29
|
"files": [
|
|
30
30
|
"dist"
|
|
31
31
|
],
|
|
32
|
-
"scripts": {
|
|
33
|
-
"build": "tsup src/index.ts --format cjs,esm --dts",
|
|
34
|
-
"dev": "tsup src/index.ts --format cjs,esm --dts --watch",
|
|
35
|
-
"test": "vitest run",
|
|
36
|
-
"test:watch": "vitest"
|
|
37
|
-
},
|
|
38
32
|
"peerDependencies": {
|
|
39
33
|
"zod": "^3.0.0 || ^4.0.0"
|
|
40
34
|
},
|
|
41
35
|
"devDependencies": {
|
|
42
|
-
"@stow/typescript-config": "workspace:*",
|
|
43
36
|
"@types/node": "^25.3.0",
|
|
44
37
|
"tsup": "^8.5.1",
|
|
45
38
|
"typescript": "^5.9.3",
|
|
46
39
|
"vitest": "^4.0.18",
|
|
47
|
-
"zod": "^4.3.6"
|
|
40
|
+
"zod": "^4.3.6",
|
|
41
|
+
"@stow/typescript-config": "0.0.0"
|
|
42
|
+
},
|
|
43
|
+
"scripts": {
|
|
44
|
+
"build": "tsup src/index.ts --format cjs,esm --dts",
|
|
45
|
+
"dev": "tsup src/index.ts --format cjs,esm --dts --watch",
|
|
46
|
+
"test": "vitest run",
|
|
47
|
+
"test:watch": "vitest"
|
|
48
48
|
}
|
|
49
|
-
}
|
|
49
|
+
}
|