sqlite-hub-client 0.7.0 → 0.8.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 +149 -0
- package/dist/database.d.ts +3 -1
- package/dist/database.js +2 -1
- package/dist/files.d.ts +135 -0
- package/dist/files.js +144 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +3 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -20,6 +20,25 @@ const db = connect({
|
|
|
20
20
|
db: "my-service",
|
|
21
21
|
});
|
|
22
22
|
|
|
23
|
+
// File upload
|
|
24
|
+
const uploaded = await db.files!.upload({
|
|
25
|
+
file: new Blob(["hello world"], { type: "text/plain" }),
|
|
26
|
+
filename: "hello.txt",
|
|
27
|
+
folderPath: "docs/examples",
|
|
28
|
+
metadata: { source: "docs" },
|
|
29
|
+
});
|
|
30
|
+
|
|
31
|
+
// File list
|
|
32
|
+
const filePage = await db.files!.list({
|
|
33
|
+
limit: 20,
|
|
34
|
+
offset: 0,
|
|
35
|
+
folderPrefix: "docs",
|
|
36
|
+
});
|
|
37
|
+
|
|
38
|
+
// Presigned browser URL (for third-party dashboards)
|
|
39
|
+
const signed = await db.files!.presign(uploaded.id, { expiresIn: 1800 });
|
|
40
|
+
console.log(signed.url);
|
|
41
|
+
|
|
23
42
|
// Create table
|
|
24
43
|
await db.createTable("users", [
|
|
25
44
|
{ name: "id", type: "INTEGER", primaryKey: true, autoIncrement: true },
|
|
@@ -306,6 +325,136 @@ await db.exec("CREATE INDEX IF NOT EXISTS idx_title ON posts (title)");
|
|
|
306
325
|
|
|
307
326
|
---
|
|
308
327
|
|
|
328
|
+
### Files
|
|
329
|
+
|
|
330
|
+
#### `db.files.upload(input)`
|
|
331
|
+
|
|
332
|
+
```ts
|
|
333
|
+
const uploaded = await db.files!.upload({
|
|
334
|
+
file: new Blob(["report"], { type: "text/plain" }),
|
|
335
|
+
filename: "report.txt",
|
|
336
|
+
folderPath: "ops/reports",
|
|
337
|
+
conflictMode: "replace", // or "error"
|
|
338
|
+
contentType: "text/plain",
|
|
339
|
+
metadata: { owner: "ops" },
|
|
340
|
+
expiresIn: 3600,
|
|
341
|
+
});
|
|
342
|
+
```
|
|
343
|
+
|
|
344
|
+
#### `db.files.list(options?)`
|
|
345
|
+
|
|
346
|
+
```ts
|
|
347
|
+
const files = await db.files!.list({
|
|
348
|
+
limit: 50,
|
|
349
|
+
offset: 0,
|
|
350
|
+
sort: "uploaded_at",
|
|
351
|
+
order: "desc",
|
|
352
|
+
folderPrefix: "ops",
|
|
353
|
+
});
|
|
354
|
+
```
|
|
355
|
+
|
|
356
|
+
#### `db.files.getMeta(fileId)`
|
|
357
|
+
|
|
358
|
+
```ts
|
|
359
|
+
const meta = await db.files!.getMeta("file-id");
|
|
360
|
+
```
|
|
361
|
+
|
|
362
|
+
#### `db.files.delete(fileId)`
|
|
363
|
+
|
|
364
|
+
```ts
|
|
365
|
+
await db.files!.delete("file-id");
|
|
366
|
+
```
|
|
367
|
+
|
|
368
|
+
#### `db.files.bulkDelete(fileIds)`
|
|
369
|
+
|
|
370
|
+
```ts
|
|
371
|
+
await db.files!.bulkDelete(["id1", "id2"]);
|
|
372
|
+
```
|
|
373
|
+
|
|
374
|
+
#### `db.files.presign(fileId, options?)`
|
|
375
|
+
|
|
376
|
+
Returns a signed URL that can be opened directly in browser without bearer token.
|
|
377
|
+
|
|
378
|
+
```ts
|
|
379
|
+
const signed = await db.files!.presign("file-id", {
|
|
380
|
+
expiresIn: 900,
|
|
381
|
+
disposition: "inline", // or "attachment"
|
|
382
|
+
});
|
|
383
|
+
|
|
384
|
+
// e.g. embed in dashboard iframe/image link
|
|
385
|
+
console.log(signed.url);
|
|
386
|
+
```
|
|
387
|
+
|
|
388
|
+
#### `db.files.batchPresign(options)`
|
|
389
|
+
|
|
390
|
+
Generate presigned URLs for multiple files at once. Maximum 100 file IDs per request.
|
|
391
|
+
|
|
392
|
+
```ts
|
|
393
|
+
const batch = await db.files!.batchPresign({
|
|
394
|
+
fileIds: ["id1", "id2", "id3"],
|
|
395
|
+
expiresIn: 900,
|
|
396
|
+
disposition: "inline",
|
|
397
|
+
});
|
|
398
|
+
|
|
399
|
+
// Check results
|
|
400
|
+
batch.results.forEach((result) => {
|
|
401
|
+
if (result.error) {
|
|
402
|
+
console.error(`Failed for ${result.file_id}: ${result.error}`);
|
|
403
|
+
} else {
|
|
404
|
+
console.log(`URL for ${result.file_id}: ${result.url}`);
|
|
405
|
+
}
|
|
406
|
+
});
|
|
407
|
+
```
|
|
408
|
+
|
|
409
|
+
#### `db.files.createFileAccessToken(options?)`
|
|
410
|
+
|
|
411
|
+
Creates a long-lived access token for file operations. Unlike presigned URLs which are per-file, this token works for all file operations on the database.
|
|
412
|
+
|
|
413
|
+
```ts
|
|
414
|
+
const tokenData = await db.files!.createFileAccessToken({
|
|
415
|
+
scope: "files:read",
|
|
416
|
+
expiresIn: 2592000, // 30 days
|
|
417
|
+
description: "Dashboard access",
|
|
418
|
+
});
|
|
419
|
+
|
|
420
|
+
// Use in query parameter or Authorization header
|
|
421
|
+
const fileUrl = `https://host/api/db/mydb/files/file-id?token=${tokenData.token}`;
|
|
422
|
+
|
|
423
|
+
// Or with Authorization header:
|
|
424
|
+
// Authorization: Bearer <token>
|
|
425
|
+
```
|
|
426
|
+
|
|
427
|
+
The token is read-only (`files:read`) and cannot be used for upload/delete operations. Default TTL is 30 days, maximum is 1 year.
|
|
428
|
+
|
|
429
|
+
#### `db.files.revokeFileAccessToken(options)`
|
|
430
|
+
|
|
431
|
+
Revokes a previously issued file access token.
|
|
432
|
+
|
|
433
|
+
```ts
|
|
434
|
+
// Revoke using the original token string
|
|
435
|
+
await db.files!.revokeFileAccessToken({
|
|
436
|
+
token: tokenData.token,
|
|
437
|
+
reason: "rotated credential",
|
|
438
|
+
});
|
|
439
|
+
|
|
440
|
+
// Or revoke by token ID + expiresAt if stored separately
|
|
441
|
+
await db.files!.revokeFileAccessToken({
|
|
442
|
+
tokenId: "token-id",
|
|
443
|
+
expiresAt: tokenData.expires_at,
|
|
444
|
+
reason: "compromised",
|
|
445
|
+
});
|
|
446
|
+
```
|
|
447
|
+
|
|
448
|
+
#### `db.files.getDownloadUrl(fileId)`
|
|
449
|
+
|
|
450
|
+
Returns the authenticated endpoint URL (requires bearer auth unless using presigned query).
|
|
451
|
+
|
|
452
|
+
```ts
|
|
453
|
+
const url = db.files!.getDownloadUrl("file-id");
|
|
454
|
+
```
|
|
455
|
+
|
|
456
|
+
---
|
|
457
|
+
|
|
309
458
|
## Architecture
|
|
310
459
|
|
|
311
460
|
```
|
package/dist/database.d.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { ExecResult, IAdapter, RawResult } from "./adapters/types.js";
|
|
2
|
+
import type { FileClient } from "./files.js";
|
|
2
3
|
export type WhereClause = Record<string, unknown>;
|
|
3
4
|
export type OrderDirection = "ASC" | "DESC";
|
|
4
5
|
export interface FindOptions {
|
|
@@ -47,7 +48,8 @@ export interface UpsertOptions {
|
|
|
47
48
|
*/
|
|
48
49
|
export declare class Database {
|
|
49
50
|
private readonly adapter;
|
|
50
|
-
|
|
51
|
+
readonly files?: FileClient;
|
|
52
|
+
constructor(adapter: IAdapter, filesClient?: FileClient);
|
|
51
53
|
/**
|
|
52
54
|
* Create a table.
|
|
53
55
|
*
|
package/dist/database.js
CHANGED
|
@@ -22,8 +22,9 @@ function isExecResult(r) {
|
|
|
22
22
|
* SQLite (via better-sqlite3 or sql.js) without changing business code.
|
|
23
23
|
*/
|
|
24
24
|
export class Database {
|
|
25
|
-
constructor(adapter) {
|
|
25
|
+
constructor(adapter, filesClient) {
|
|
26
26
|
this.adapter = adapter;
|
|
27
|
+
this.files = filesClient;
|
|
27
28
|
}
|
|
28
29
|
// ── Schema ──────────────────────────────────────────────────────────────
|
|
29
30
|
/**
|
package/dist/files.d.ts
ADDED
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
import type { HttpAdapterOptions } from "./adapters/http.js";
|
|
2
|
+
export interface FileListOptions {
|
|
3
|
+
limit?: number;
|
|
4
|
+
offset?: number;
|
|
5
|
+
sort?: "uploaded_at" | "size_bytes" | "filename" | "folder_path";
|
|
6
|
+
order?: "asc" | "desc";
|
|
7
|
+
folderPrefix?: string;
|
|
8
|
+
}
|
|
9
|
+
export interface StoredFile {
|
|
10
|
+
id: string;
|
|
11
|
+
db_name: string;
|
|
12
|
+
content_hash: string;
|
|
13
|
+
filename: string;
|
|
14
|
+
folder_path: string;
|
|
15
|
+
content_type: string | null;
|
|
16
|
+
size_bytes: number;
|
|
17
|
+
storage_path?: string;
|
|
18
|
+
uploaded_at: string;
|
|
19
|
+
expires_at: string | null;
|
|
20
|
+
metadata: string | null;
|
|
21
|
+
}
|
|
22
|
+
export interface FileListResponse {
|
|
23
|
+
files: StoredFile[];
|
|
24
|
+
total: number;
|
|
25
|
+
offset: number;
|
|
26
|
+
limit: number;
|
|
27
|
+
}
|
|
28
|
+
export interface UploadFileInput {
|
|
29
|
+
file: Blob | Uint8Array | ArrayBuffer;
|
|
30
|
+
filename?: string;
|
|
31
|
+
folderPath?: string;
|
|
32
|
+
conflictMode?: "replace" | "error";
|
|
33
|
+
contentType?: string;
|
|
34
|
+
metadata?: Record<string, unknown>;
|
|
35
|
+
expiresIn?: number;
|
|
36
|
+
}
|
|
37
|
+
export interface UploadFileResponse {
|
|
38
|
+
id: string;
|
|
39
|
+
filename: string;
|
|
40
|
+
folder_path: string;
|
|
41
|
+
size_bytes: number;
|
|
42
|
+
content_type: string | null;
|
|
43
|
+
url: string;
|
|
44
|
+
uploaded_at: string;
|
|
45
|
+
expires_at: string | null;
|
|
46
|
+
}
|
|
47
|
+
export interface FileMetaResponse {
|
|
48
|
+
id: string;
|
|
49
|
+
filename: string;
|
|
50
|
+
folder_path: string;
|
|
51
|
+
content_type: string | null;
|
|
52
|
+
size_bytes: number;
|
|
53
|
+
uploaded_at: string;
|
|
54
|
+
expires_at: string | null;
|
|
55
|
+
metadata: Record<string, unknown> | null;
|
|
56
|
+
content_hash: string;
|
|
57
|
+
}
|
|
58
|
+
export interface BulkDeleteFilesResponse {
|
|
59
|
+
deleted: number;
|
|
60
|
+
failed: number;
|
|
61
|
+
}
|
|
62
|
+
export interface PresignFileOptions {
|
|
63
|
+
expiresIn?: number;
|
|
64
|
+
disposition?: "inline" | "attachment";
|
|
65
|
+
}
|
|
66
|
+
export interface PresignFileResponse {
|
|
67
|
+
url: string;
|
|
68
|
+
expires_at: string;
|
|
69
|
+
expires_in: number;
|
|
70
|
+
disposition: "inline" | "attachment";
|
|
71
|
+
token_type: "signed_query";
|
|
72
|
+
}
|
|
73
|
+
export interface BatchPresignOptions {
|
|
74
|
+
fileIds: string[];
|
|
75
|
+
expiresIn?: number;
|
|
76
|
+
disposition?: "inline" | "attachment";
|
|
77
|
+
}
|
|
78
|
+
export interface BatchPresignResult {
|
|
79
|
+
file_id: string;
|
|
80
|
+
url?: string;
|
|
81
|
+
expires_at?: string;
|
|
82
|
+
expires_in?: number;
|
|
83
|
+
disposition?: "inline" | "attachment";
|
|
84
|
+
error?: string;
|
|
85
|
+
}
|
|
86
|
+
export interface BatchPresignResponse {
|
|
87
|
+
results: BatchPresignResult[];
|
|
88
|
+
token_type: "signed_query";
|
|
89
|
+
total: number;
|
|
90
|
+
successful: number;
|
|
91
|
+
failed: number;
|
|
92
|
+
}
|
|
93
|
+
export interface CreateFileAccessTokenOptions {
|
|
94
|
+
scope?: "files:read";
|
|
95
|
+
expiresIn?: number;
|
|
96
|
+
description?: string;
|
|
97
|
+
}
|
|
98
|
+
export interface FileAccessTokenResponse {
|
|
99
|
+
token_id: string;
|
|
100
|
+
token: string;
|
|
101
|
+
token_type: "bearer";
|
|
102
|
+
expires_at: string;
|
|
103
|
+
expires_in: number;
|
|
104
|
+
scope: string;
|
|
105
|
+
description?: string;
|
|
106
|
+
usage: string;
|
|
107
|
+
}
|
|
108
|
+
export interface RevokeFileAccessTokenOptions {
|
|
109
|
+
token?: string;
|
|
110
|
+
tokenId?: string;
|
|
111
|
+
expiresAt?: string;
|
|
112
|
+
reason?: string;
|
|
113
|
+
}
|
|
114
|
+
export interface RevokeFileAccessTokenResponse {
|
|
115
|
+
success: boolean;
|
|
116
|
+
token_id: string;
|
|
117
|
+
revoked_at: string;
|
|
118
|
+
}
|
|
119
|
+
export declare class FileClient {
|
|
120
|
+
private readonly options;
|
|
121
|
+
private readonly baseUrl;
|
|
122
|
+
private readonly basePath;
|
|
123
|
+
constructor(options: HttpAdapterOptions);
|
|
124
|
+
private requestJson;
|
|
125
|
+
list(options?: FileListOptions): Promise<FileListResponse>;
|
|
126
|
+
upload(input: UploadFileInput): Promise<UploadFileResponse>;
|
|
127
|
+
getMeta(fileId: string): Promise<FileMetaResponse>;
|
|
128
|
+
delete(fileId: string): Promise<void>;
|
|
129
|
+
bulkDelete(fileIds: string[]): Promise<BulkDeleteFilesResponse>;
|
|
130
|
+
presign(fileId: string, options?: PresignFileOptions): Promise<PresignFileResponse>;
|
|
131
|
+
batchPresign(options: BatchPresignOptions): Promise<BatchPresignResponse>;
|
|
132
|
+
createFileAccessToken(options?: CreateFileAccessTokenOptions): Promise<FileAccessTokenResponse>;
|
|
133
|
+
revokeFileAccessToken(options: RevokeFileAccessTokenOptions): Promise<RevokeFileAccessTokenResponse>;
|
|
134
|
+
getDownloadUrl(fileId: string): string;
|
|
135
|
+
}
|
package/dist/files.js
ADDED
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
function toBlob(file, contentType) {
|
|
2
|
+
if (file instanceof Blob)
|
|
3
|
+
return file;
|
|
4
|
+
if (file instanceof Uint8Array)
|
|
5
|
+
return new Blob([file], { type: contentType });
|
|
6
|
+
return new Blob([new Uint8Array(file)], { type: contentType });
|
|
7
|
+
}
|
|
8
|
+
export class FileClient {
|
|
9
|
+
constructor(options) {
|
|
10
|
+
this.options = options;
|
|
11
|
+
this.baseUrl = options.url.replace(/\/$/, "");
|
|
12
|
+
this.basePath = `/api/db/${encodeURIComponent(options.db)}/files`;
|
|
13
|
+
}
|
|
14
|
+
async requestJson(path, init = {}) {
|
|
15
|
+
const headers = new Headers(init.headers ?? {});
|
|
16
|
+
headers.set("Authorization", `Bearer ${this.options.token}`);
|
|
17
|
+
const res = await fetch(`${this.baseUrl}${path}`, {
|
|
18
|
+
...init,
|
|
19
|
+
headers,
|
|
20
|
+
});
|
|
21
|
+
if (res.status === 204) {
|
|
22
|
+
return undefined;
|
|
23
|
+
}
|
|
24
|
+
const body = (await res.json().catch(() => null));
|
|
25
|
+
if (!res.ok) {
|
|
26
|
+
throw new Error(body?.error ?? `sqlite-hub: HTTP ${res.status} (db: "${this.options.db}")`);
|
|
27
|
+
}
|
|
28
|
+
return body;
|
|
29
|
+
}
|
|
30
|
+
async list(options = {}) {
|
|
31
|
+
const qs = new URLSearchParams();
|
|
32
|
+
if (options.limit !== undefined)
|
|
33
|
+
qs.set("limit", String(options.limit));
|
|
34
|
+
if (options.offset !== undefined)
|
|
35
|
+
qs.set("offset", String(options.offset));
|
|
36
|
+
if (options.sort)
|
|
37
|
+
qs.set("sort", options.sort);
|
|
38
|
+
if (options.order)
|
|
39
|
+
qs.set("order", options.order);
|
|
40
|
+
if (options.folderPrefix)
|
|
41
|
+
qs.set("folder_prefix", options.folderPrefix);
|
|
42
|
+
const suffix = qs.toString() ? `?${qs.toString()}` : "";
|
|
43
|
+
return this.requestJson(`${this.basePath}${suffix}`);
|
|
44
|
+
}
|
|
45
|
+
async upload(input) {
|
|
46
|
+
const formData = new FormData();
|
|
47
|
+
const blob = toBlob(input.file, input.contentType);
|
|
48
|
+
const filename = input.filename ?? "file";
|
|
49
|
+
formData.append("file", blob, filename);
|
|
50
|
+
if (input.filename)
|
|
51
|
+
formData.append("filename", input.filename);
|
|
52
|
+
if (input.folderPath)
|
|
53
|
+
formData.append("folder_path", input.folderPath);
|
|
54
|
+
if (input.conflictMode)
|
|
55
|
+
formData.append("conflict_mode", input.conflictMode);
|
|
56
|
+
if (input.contentType)
|
|
57
|
+
formData.append("content_type", input.contentType);
|
|
58
|
+
if (input.metadata)
|
|
59
|
+
formData.append("metadata", JSON.stringify(input.metadata));
|
|
60
|
+
if (input.expiresIn !== undefined)
|
|
61
|
+
formData.append("expires_in", String(input.expiresIn));
|
|
62
|
+
const headers = new Headers({ Authorization: `Bearer ${this.options.token}` });
|
|
63
|
+
const res = await fetch(`${this.baseUrl}${this.basePath}`, {
|
|
64
|
+
method: "POST",
|
|
65
|
+
headers,
|
|
66
|
+
body: formData,
|
|
67
|
+
});
|
|
68
|
+
const body = (await res.json().catch(() => null));
|
|
69
|
+
if (!res.ok || !body) {
|
|
70
|
+
throw new Error(body?.error ?? `sqlite-hub: HTTP ${res.status} (db: "${this.options.db}")`);
|
|
71
|
+
}
|
|
72
|
+
return body;
|
|
73
|
+
}
|
|
74
|
+
async getMeta(fileId) {
|
|
75
|
+
return this.requestJson(`${this.basePath}/${encodeURIComponent(fileId)}/meta`);
|
|
76
|
+
}
|
|
77
|
+
async delete(fileId) {
|
|
78
|
+
await this.requestJson(`${this.basePath}/${encodeURIComponent(fileId)}`, {
|
|
79
|
+
method: "DELETE",
|
|
80
|
+
});
|
|
81
|
+
}
|
|
82
|
+
async bulkDelete(fileIds) {
|
|
83
|
+
return this.requestJson(`${this.basePath}/bulk-delete`, {
|
|
84
|
+
method: "POST",
|
|
85
|
+
headers: { "Content-Type": "application/json" },
|
|
86
|
+
body: JSON.stringify({ file_ids: fileIds }),
|
|
87
|
+
});
|
|
88
|
+
}
|
|
89
|
+
async presign(fileId, options = {}) {
|
|
90
|
+
return this.requestJson(`${this.basePath}/${encodeURIComponent(fileId)}/presign`, {
|
|
91
|
+
method: "POST",
|
|
92
|
+
headers: { "Content-Type": "application/json" },
|
|
93
|
+
body: JSON.stringify({
|
|
94
|
+
...(options.expiresIn !== undefined ? { expires_in: options.expiresIn } : {}),
|
|
95
|
+
...(options.disposition ? { disposition: options.disposition } : {}),
|
|
96
|
+
}),
|
|
97
|
+
});
|
|
98
|
+
}
|
|
99
|
+
async batchPresign(options) {
|
|
100
|
+
return this.requestJson(`${this.basePath}/presign/batch`, {
|
|
101
|
+
method: "POST",
|
|
102
|
+
headers: { "Content-Type": "application/json" },
|
|
103
|
+
body: JSON.stringify({
|
|
104
|
+
file_ids: options.fileIds,
|
|
105
|
+
...(options.expiresIn !== undefined ? { expires_in: options.expiresIn } : {}),
|
|
106
|
+
...(options.disposition ? { disposition: options.disposition } : {}),
|
|
107
|
+
}),
|
|
108
|
+
});
|
|
109
|
+
}
|
|
110
|
+
async createFileAccessToken(options = {}) {
|
|
111
|
+
const tokenPath = `/api/db/${encodeURIComponent(this.options.db)}/tokens/files`;
|
|
112
|
+
return this.requestJson(tokenPath, {
|
|
113
|
+
method: "POST",
|
|
114
|
+
headers: { "Content-Type": "application/json" },
|
|
115
|
+
body: JSON.stringify({
|
|
116
|
+
scope: "files:read",
|
|
117
|
+
...(options.expiresIn !== undefined ? { expires_in: options.expiresIn } : {}),
|
|
118
|
+
...(options.description ? { description: options.description } : {}),
|
|
119
|
+
}),
|
|
120
|
+
});
|
|
121
|
+
}
|
|
122
|
+
async revokeFileAccessToken(options) {
|
|
123
|
+
const tokenPath = `/api/db/${encodeURIComponent(this.options.db)}/tokens/files/revoke`;
|
|
124
|
+
const payload = {
|
|
125
|
+
...(options.token ? { token: options.token } : {}),
|
|
126
|
+
...(options.reason ? { reason: options.reason } : {}),
|
|
127
|
+
};
|
|
128
|
+
if (!options.token) {
|
|
129
|
+
if (!options.tokenId || !options.expiresAt) {
|
|
130
|
+
throw new Error("tokenId and expiresAt are required when token is not provided");
|
|
131
|
+
}
|
|
132
|
+
payload.token_id = options.tokenId;
|
|
133
|
+
payload.expires_at = options.expiresAt;
|
|
134
|
+
}
|
|
135
|
+
return this.requestJson(tokenPath, {
|
|
136
|
+
method: "POST",
|
|
137
|
+
headers: { "Content-Type": "application/json" },
|
|
138
|
+
body: JSON.stringify(payload),
|
|
139
|
+
});
|
|
140
|
+
}
|
|
141
|
+
getDownloadUrl(fileId) {
|
|
142
|
+
return `${this.baseUrl}${this.basePath}/${encodeURIComponent(fileId)}`;
|
|
143
|
+
}
|
|
144
|
+
}
|
package/dist/index.d.ts
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
export { Database } from "./database.js";
|
|
2
2
|
export type { ColumnDef, CreateIndexOptions, CreateTableOptions, FindOptions, OrderDirection, UpsertOptions, WhereClause } from "./database.js";
|
|
3
|
+
export { FileClient, } from "./files.js";
|
|
4
|
+
export type { BatchPresignOptions, BatchPresignResponse, BatchPresignResult, BulkDeleteFilesResponse, CreateFileAccessTokenOptions, FileAccessTokenResponse, FileListOptions, FileListResponse, FileMetaResponse, PresignFileOptions, PresignFileResponse, RevokeFileAccessTokenOptions, RevokeFileAccessTokenResponse, StoredFile, UploadFileInput, UploadFileResponse, } from "./files.js";
|
|
3
5
|
export { HttpAdapter } from "./adapters/http.js";
|
|
4
6
|
export type { HttpAdapterOptions } from "./adapters/http.js";
|
|
5
7
|
export type { ColumnHeader, ExecResult, IAdapter, QueryResult, RawResult } from "./adapters/types.js";
|
package/dist/index.js
CHANGED
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
export { Database } from "./database.js";
|
|
2
|
+
export { FileClient, } from "./files.js";
|
|
2
3
|
export { HttpAdapter } from "./adapters/http.js";
|
|
3
4
|
// ── Convenience factory ──────────────────────────────────────────────────────
|
|
4
5
|
import { HttpAdapter } from "./adapters/http.js";
|
|
5
6
|
import { Database } from "./database.js";
|
|
7
|
+
import { FileClient } from "./files.js";
|
|
6
8
|
/**
|
|
7
9
|
* Create a Database connected to a sqlite-hub service over HTTP.
|
|
8
10
|
*
|
|
@@ -14,6 +16,6 @@ import { Database } from "./database.js";
|
|
|
14
16
|
* });
|
|
15
17
|
*/
|
|
16
18
|
export function connect(options) {
|
|
17
|
-
return new Database(new HttpAdapter(options));
|
|
19
|
+
return new Database(new HttpAdapter(options), new FileClient(options));
|
|
18
20
|
}
|
|
19
21
|
export default connect;
|