@howells/stow-server 0.1.0
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/README.md +161 -0
- package/dist/index.d.mts +302 -0
- package/dist/index.d.ts +302 -0
- package/dist/index.js +477 -0
- package/dist/index.mjs +451 -0
- package/package.json +49 -0
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,302 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Stow Server SDK
|
|
3
|
+
*
|
|
4
|
+
* Server-side SDK for Node.js environments.
|
|
5
|
+
* Use this to upload files, generate presigned URLs, and manage files from your server.
|
|
6
|
+
*
|
|
7
|
+
* @example
|
|
8
|
+
* ```typescript
|
|
9
|
+
* import { StowServer } from "@howells/stow-server";
|
|
10
|
+
*
|
|
11
|
+
* // Scoped API key — bucket is implicit
|
|
12
|
+
* const stow = new StowServer(process.env.STOW_API_KEY!);
|
|
13
|
+
*
|
|
14
|
+
* // Global API key — specify bucket
|
|
15
|
+
* const stow = new StowServer({
|
|
16
|
+
* apiKey: process.env.STOW_API_KEY!,
|
|
17
|
+
* bucket: "my-blog",
|
|
18
|
+
* });
|
|
19
|
+
*
|
|
20
|
+
* const result = await stow.uploadFromUrl("https://example.com/image.jpg", "image.jpg");
|
|
21
|
+
* console.log(result.url);
|
|
22
|
+
* ```
|
|
23
|
+
*/
|
|
24
|
+
declare class StowError extends Error {
|
|
25
|
+
readonly status: number;
|
|
26
|
+
readonly code?: string;
|
|
27
|
+
constructor(message: string, status: number, code?: string);
|
|
28
|
+
}
|
|
29
|
+
interface StowServerConfig {
|
|
30
|
+
apiKey: string;
|
|
31
|
+
baseUrl?: string;
|
|
32
|
+
/** Default bucket name or ID. Required for global API keys. */
|
|
33
|
+
bucket?: string;
|
|
34
|
+
}
|
|
35
|
+
interface UploadResult {
|
|
36
|
+
key: string;
|
|
37
|
+
url: string | null;
|
|
38
|
+
size: number;
|
|
39
|
+
contentType: string;
|
|
40
|
+
metadata?: Record<string, string>;
|
|
41
|
+
}
|
|
42
|
+
interface TransformOptions {
|
|
43
|
+
width?: number;
|
|
44
|
+
height?: number;
|
|
45
|
+
quality?: number;
|
|
46
|
+
format?: "webp" | "avif" | "jpeg" | "png";
|
|
47
|
+
}
|
|
48
|
+
interface ListFilesResult {
|
|
49
|
+
files: Array<{
|
|
50
|
+
key: string;
|
|
51
|
+
size: number;
|
|
52
|
+
lastModified: string;
|
|
53
|
+
url: string | null;
|
|
54
|
+
metadata?: Record<string, string>;
|
|
55
|
+
}>;
|
|
56
|
+
nextCursor: string | null;
|
|
57
|
+
}
|
|
58
|
+
interface DropResult {
|
|
59
|
+
shortId: string;
|
|
60
|
+
url: string;
|
|
61
|
+
filename: string;
|
|
62
|
+
size: number;
|
|
63
|
+
contentType: string;
|
|
64
|
+
}
|
|
65
|
+
interface Drop {
|
|
66
|
+
id: string;
|
|
67
|
+
shortId: string;
|
|
68
|
+
url: string;
|
|
69
|
+
filename: string;
|
|
70
|
+
size: number;
|
|
71
|
+
contentType: string;
|
|
72
|
+
createdAt: string;
|
|
73
|
+
}
|
|
74
|
+
interface ListDropsResult {
|
|
75
|
+
drops: Drop[];
|
|
76
|
+
usage: {
|
|
77
|
+
bytes: number;
|
|
78
|
+
limit: number;
|
|
79
|
+
};
|
|
80
|
+
}
|
|
81
|
+
interface PresignResult {
|
|
82
|
+
/** The file key that will be created */
|
|
83
|
+
fileKey: string;
|
|
84
|
+
/** URL to PUT the file to */
|
|
85
|
+
uploadUrl: string;
|
|
86
|
+
/** The R2 key for the file */
|
|
87
|
+
r2Key: string;
|
|
88
|
+
/** URL to call to confirm the upload */
|
|
89
|
+
confirmUrl: string;
|
|
90
|
+
}
|
|
91
|
+
interface PresignRequest {
|
|
92
|
+
filename: string;
|
|
93
|
+
contentType: string;
|
|
94
|
+
/** File size in bytes */
|
|
95
|
+
size: number;
|
|
96
|
+
/** Optional route/folder */
|
|
97
|
+
route?: string;
|
|
98
|
+
/** Override the default bucket */
|
|
99
|
+
bucket?: string;
|
|
100
|
+
/** Custom metadata to attach to the file */
|
|
101
|
+
metadata?: Record<string, string>;
|
|
102
|
+
}
|
|
103
|
+
interface ConfirmUploadRequest {
|
|
104
|
+
fileKey: string;
|
|
105
|
+
size: number;
|
|
106
|
+
contentType: string;
|
|
107
|
+
/** Override the default bucket */
|
|
108
|
+
bucket?: string;
|
|
109
|
+
/** Custom metadata to attach to the file */
|
|
110
|
+
metadata?: Record<string, string>;
|
|
111
|
+
}
|
|
112
|
+
interface SimilarSearchRequest {
|
|
113
|
+
/** Find files similar to this file key */
|
|
114
|
+
fileKey?: string;
|
|
115
|
+
/** Search directly with a vector (1024 dimensions) */
|
|
116
|
+
vector?: number[];
|
|
117
|
+
/** Bucket name or ID to scope search */
|
|
118
|
+
bucket?: string;
|
|
119
|
+
/** Max results (default 10, max 50) */
|
|
120
|
+
limit?: number;
|
|
121
|
+
}
|
|
122
|
+
interface SimilarSearchResult {
|
|
123
|
+
results: Array<{
|
|
124
|
+
id: string;
|
|
125
|
+
key: string;
|
|
126
|
+
bucketId: string;
|
|
127
|
+
originalFilename: string | null;
|
|
128
|
+
size: number;
|
|
129
|
+
contentType: string;
|
|
130
|
+
metadata: Record<string, string> | null;
|
|
131
|
+
embeddingStatus: string | null;
|
|
132
|
+
similarity: number;
|
|
133
|
+
createdAt: string;
|
|
134
|
+
}>;
|
|
135
|
+
}
|
|
136
|
+
declare class StowServer {
|
|
137
|
+
private readonly apiKey;
|
|
138
|
+
private readonly baseUrl;
|
|
139
|
+
private readonly bucket?;
|
|
140
|
+
constructor(config: StowServerConfig | string);
|
|
141
|
+
/**
|
|
142
|
+
* Get the base URL for this instance (used by client SDK)
|
|
143
|
+
*/
|
|
144
|
+
getBaseUrl(): string;
|
|
145
|
+
/**
|
|
146
|
+
* Resolve the effective bucket for this request.
|
|
147
|
+
* Per-call override > constructor default.
|
|
148
|
+
*/
|
|
149
|
+
private resolveBucket;
|
|
150
|
+
/**
|
|
151
|
+
* Append bucket query param to a URL path if set.
|
|
152
|
+
*/
|
|
153
|
+
private withBucket;
|
|
154
|
+
/**
|
|
155
|
+
* Make an API request with proper error handling
|
|
156
|
+
*/
|
|
157
|
+
private request;
|
|
158
|
+
/**
|
|
159
|
+
* Upload a file directly from the server
|
|
160
|
+
*/
|
|
161
|
+
uploadFile(file: Buffer | Blob, options?: {
|
|
162
|
+
filename?: string;
|
|
163
|
+
contentType?: string;
|
|
164
|
+
route?: string;
|
|
165
|
+
/** Override the default bucket for this request */
|
|
166
|
+
bucket?: string;
|
|
167
|
+
/** Custom metadata to attach to the file */
|
|
168
|
+
metadata?: Record<string, string>;
|
|
169
|
+
}): Promise<UploadResult>;
|
|
170
|
+
/**
|
|
171
|
+
* Upload a file from a URL (server-side fetch + upload)
|
|
172
|
+
*/
|
|
173
|
+
uploadFromUrl(url: string, filename: string, options?: {
|
|
174
|
+
bucket?: string;
|
|
175
|
+
metadata?: Record<string, string>;
|
|
176
|
+
}): Promise<UploadResult>;
|
|
177
|
+
/**
|
|
178
|
+
* Get a presigned URL for direct client-side upload.
|
|
179
|
+
*
|
|
180
|
+
* This enables uploads that bypass your server entirely:
|
|
181
|
+
* 1. Client calls your endpoint
|
|
182
|
+
* 2. Your endpoint calls this method
|
|
183
|
+
* 3. Client PUTs directly to the returned uploadUrl
|
|
184
|
+
* 4. Client calls confirmUpload to finalize
|
|
185
|
+
*/
|
|
186
|
+
getPresignedUrl(request: PresignRequest): Promise<PresignResult>;
|
|
187
|
+
/**
|
|
188
|
+
* Confirm a presigned upload after the client has uploaded to R2.
|
|
189
|
+
* This creates the file record in the database.
|
|
190
|
+
*/
|
|
191
|
+
confirmUpload(request: ConfirmUploadRequest): Promise<UploadResult>;
|
|
192
|
+
/**
|
|
193
|
+
* List files in the bucket
|
|
194
|
+
*/
|
|
195
|
+
listFiles(options?: {
|
|
196
|
+
prefix?: string;
|
|
197
|
+
limit?: number;
|
|
198
|
+
cursor?: string;
|
|
199
|
+
bucket?: string;
|
|
200
|
+
/** Filter by tag slug */
|
|
201
|
+
tag?: string;
|
|
202
|
+
}): Promise<ListFilesResult>;
|
|
203
|
+
/**
|
|
204
|
+
* Delete a file by key
|
|
205
|
+
*/
|
|
206
|
+
deleteFile(key: string, options?: {
|
|
207
|
+
bucket?: string;
|
|
208
|
+
}): Promise<void>;
|
|
209
|
+
/**
|
|
210
|
+
* Update metadata on an existing file
|
|
211
|
+
*/
|
|
212
|
+
updateFileMetadata(key: string, metadata: Record<string, string>, options?: {
|
|
213
|
+
bucket?: string;
|
|
214
|
+
}): Promise<{
|
|
215
|
+
key: string;
|
|
216
|
+
metadata: Record<string, string>;
|
|
217
|
+
}>;
|
|
218
|
+
/**
|
|
219
|
+
* Get a transform URL for an image.
|
|
220
|
+
*
|
|
221
|
+
* Appends transform query params (?w=, ?h=, ?q=, ?f=) to a file URL.
|
|
222
|
+
* Transforms are applied at the edge by the Cloudflare Worker — no
|
|
223
|
+
* server round-trip needed.
|
|
224
|
+
*
|
|
225
|
+
* @param url - Full file URL (e.g. from upload result's fileUrl)
|
|
226
|
+
* @param options - Transform options (width, height, quality, format)
|
|
227
|
+
*/
|
|
228
|
+
getTransformUrl(url: string, options?: TransformOptions): string;
|
|
229
|
+
/**
|
|
230
|
+
* Tags namespace for creating, listing, and deleting tags
|
|
231
|
+
*/
|
|
232
|
+
get tags(): {
|
|
233
|
+
list: () => Promise<{
|
|
234
|
+
tags: Array<{
|
|
235
|
+
id: string;
|
|
236
|
+
name: string;
|
|
237
|
+
slug: string;
|
|
238
|
+
color: string | null;
|
|
239
|
+
createdAt: string;
|
|
240
|
+
}>;
|
|
241
|
+
}>;
|
|
242
|
+
create: (params: {
|
|
243
|
+
name: string;
|
|
244
|
+
color?: string;
|
|
245
|
+
}) => Promise<{
|
|
246
|
+
id: string;
|
|
247
|
+
name: string;
|
|
248
|
+
slug: string;
|
|
249
|
+
color: string | null;
|
|
250
|
+
createdAt: string;
|
|
251
|
+
}>;
|
|
252
|
+
delete: (id: string) => Promise<void>;
|
|
253
|
+
};
|
|
254
|
+
private listTags;
|
|
255
|
+
private createTag;
|
|
256
|
+
private deleteTag;
|
|
257
|
+
/**
|
|
258
|
+
* Add tags to a file
|
|
259
|
+
*/
|
|
260
|
+
addTags(key: string, tagIds: string[], options?: {
|
|
261
|
+
bucket?: string;
|
|
262
|
+
}): Promise<void>;
|
|
263
|
+
/**
|
|
264
|
+
* Remove a tag from a file
|
|
265
|
+
*/
|
|
266
|
+
removeTag(key: string, tagId: string, options?: {
|
|
267
|
+
bucket?: string;
|
|
268
|
+
}): Promise<void>;
|
|
269
|
+
/**
|
|
270
|
+
* Search namespace for vector similarity search
|
|
271
|
+
*/
|
|
272
|
+
get search(): {
|
|
273
|
+
similar: (params: SimilarSearchRequest) => Promise<SimilarSearchResult>;
|
|
274
|
+
};
|
|
275
|
+
private searchSimilar;
|
|
276
|
+
/**
|
|
277
|
+
* Upload a file as a drop (quick share)
|
|
278
|
+
*
|
|
279
|
+
* Drops are simpler than bucket uploads - just upload and get a URL.
|
|
280
|
+
* No bucket setup required. 1GB storage limit per user.
|
|
281
|
+
*
|
|
282
|
+
* @example
|
|
283
|
+
* ```typescript
|
|
284
|
+
* const drop = await stow.drop(buffer, { filename: "screenshot.png" });
|
|
285
|
+
* console.log(drop.url); // https://d.stow.sh/x7kQ3m
|
|
286
|
+
* ```
|
|
287
|
+
*/
|
|
288
|
+
drop(file: Buffer | Blob, options?: {
|
|
289
|
+
filename?: string;
|
|
290
|
+
contentType?: string;
|
|
291
|
+
}): Promise<DropResult>;
|
|
292
|
+
/**
|
|
293
|
+
* List all drops for the authenticated user
|
|
294
|
+
*/
|
|
295
|
+
listDrops(): Promise<ListDropsResult>;
|
|
296
|
+
/**
|
|
297
|
+
* Delete a drop by ID
|
|
298
|
+
*/
|
|
299
|
+
deleteDrop(id: string): Promise<void>;
|
|
300
|
+
}
|
|
301
|
+
|
|
302
|
+
export { type ConfirmUploadRequest, type Drop, type DropResult, type ListDropsResult, type ListFilesResult, type PresignRequest, type PresignResult, type SimilarSearchRequest, type SimilarSearchResult, StowError, StowServer, type StowServerConfig, type TransformOptions, type UploadResult };
|