@koolbase/core 12.14.0 → 12.16.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/dist/cjs/auth.d.ts +31 -1
- package/dist/cjs/auth.js +167 -20
- package/dist/cjs/database.js +2 -2
- package/dist/cjs/fiscal.js +2 -2
- package/dist/cjs/functions.js +2 -2
- package/dist/cjs/index.d.ts +3 -0
- package/dist/cjs/index.js +3 -1
- package/dist/cjs/network.d.ts +14 -0
- package/dist/cjs/network.js +60 -0
- package/dist/cjs/storage-errors.d.ts +39 -0
- package/dist/cjs/storage-errors.js +75 -1
- package/dist/cjs/storage-files.d.ts +53 -0
- package/dist/cjs/storage-files.js +61 -0
- package/dist/cjs/storage-transfer.d.ts +88 -0
- package/dist/cjs/storage-transfer.js +214 -0
- package/dist/cjs/storage.d.ts +41 -0
- package/dist/cjs/storage.js +101 -18
- package/dist/cjs/sync-engine.js +3 -3
- package/dist/cjs/types.d.ts +19 -1
- package/dist/esm/auth.d.ts +31 -1
- package/dist/esm/auth.js +168 -21
- package/dist/esm/database.js +3 -3
- package/dist/esm/fiscal.js +3 -3
- package/dist/esm/functions.js +3 -3
- package/dist/esm/index.d.ts +3 -0
- package/dist/esm/index.js +1 -0
- package/dist/esm/network.d.ts +14 -0
- package/dist/esm/network.js +58 -0
- package/dist/esm/storage-errors.d.ts +39 -0
- package/dist/esm/storage-errors.js +69 -0
- package/dist/esm/storage-files.d.ts +53 -0
- package/dist/esm/storage-files.js +56 -0
- package/dist/esm/storage-transfer.d.ts +88 -0
- package/dist/esm/storage-transfer.js +208 -0
- package/dist/esm/storage.d.ts +41 -0
- package/dist/esm/storage.js +102 -19
- package/dist/esm/sync-engine.js +4 -4
- package/dist/esm/types.d.ts +19 -1
- package/package.json +1 -1
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
/** What a listing is ordered by. */
|
|
2
|
+
export type KoolbaseFileSort = 'path' | 'createdAt' | 'updatedAt' | 'size';
|
|
3
|
+
export interface ListFilesOptions {
|
|
4
|
+
bucket: string;
|
|
5
|
+
/** Only files whose path starts with this, taken literally. */
|
|
6
|
+
prefix?: string;
|
|
7
|
+
/** Files per page: 50 unless set, at most 100. */
|
|
8
|
+
limit?: number;
|
|
9
|
+
/** A page's `nextCursor`, for the page after it. */
|
|
10
|
+
cursor?: string;
|
|
11
|
+
/** By path unless set. */
|
|
12
|
+
sort?: KoolbaseFileSort;
|
|
13
|
+
/** Z to A, newest first, largest first. */
|
|
14
|
+
descending?: boolean;
|
|
15
|
+
}
|
|
16
|
+
/** One file. */
|
|
17
|
+
export interface KoolbaseFileInfo {
|
|
18
|
+
/** Its path in the bucket: what a record stores to point at it. */
|
|
19
|
+
path: string;
|
|
20
|
+
/** The last part of its path. */
|
|
21
|
+
name: string;
|
|
22
|
+
size: number;
|
|
23
|
+
contentType: string | null;
|
|
24
|
+
etag: string | null;
|
|
25
|
+
metadata: Record<string, string>;
|
|
26
|
+
versionId: string | null;
|
|
27
|
+
/** Who uploaded it: a project user's id; null when the project did. */
|
|
28
|
+
uploadedBy: string | null;
|
|
29
|
+
/** ISO 8601. */
|
|
30
|
+
createdAt: string;
|
|
31
|
+
/** ISO 8601. */
|
|
32
|
+
updatedAt: string;
|
|
33
|
+
/**
|
|
34
|
+
* Its permanent link, while its bucket is public; null otherwise -- ask
|
|
35
|
+
* for a download link instead.
|
|
36
|
+
*/
|
|
37
|
+
publicUrl: string | null;
|
|
38
|
+
}
|
|
39
|
+
/** One page of a listing. */
|
|
40
|
+
export interface KoolbaseFilePage {
|
|
41
|
+
files: KoolbaseFileInfo[];
|
|
42
|
+
/**
|
|
43
|
+
* Pass to the next call for the page after this one; null at the end. A
|
|
44
|
+
* page can hold fewer files than asked for -- the server passes over
|
|
45
|
+
* files you may not view -- and still have a next one.
|
|
46
|
+
*/
|
|
47
|
+
nextCursor: string | null;
|
|
48
|
+
hasMore: boolean;
|
|
49
|
+
}
|
|
50
|
+
/** The query string for a listing. */
|
|
51
|
+
export declare function listFilesQuery(o: ListFilesOptions): string;
|
|
52
|
+
export declare function fileInfoFromJson(j: Record<string, unknown>): KoolbaseFileInfo;
|
|
53
|
+
export declare function filePageFromJson(j: Record<string, unknown>): KoolbaseFilePage;
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
// A bucket's files, as an app sees them (S1).
|
|
3
|
+
//
|
|
4
|
+
// The server applies the bucket's view rule to every file: a listing holds
|
|
5
|
+
// only files the signed-in person may view, and says nothing of the rest.
|
|
6
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
7
|
+
exports.listFilesQuery = listFilesQuery;
|
|
8
|
+
exports.fileInfoFromJson = fileInfoFromJson;
|
|
9
|
+
exports.filePageFromJson = filePageFromJson;
|
|
10
|
+
const sortWire = {
|
|
11
|
+
path: 'path',
|
|
12
|
+
createdAt: 'created_at',
|
|
13
|
+
updatedAt: 'updated_at',
|
|
14
|
+
size: 'size',
|
|
15
|
+
};
|
|
16
|
+
/** The query string for a listing. */
|
|
17
|
+
function listFilesQuery(o) {
|
|
18
|
+
const q = new URLSearchParams();
|
|
19
|
+
q.set('bucket', o.bucket);
|
|
20
|
+
if (o.prefix)
|
|
21
|
+
q.set('prefix', o.prefix);
|
|
22
|
+
if (o.limit != null)
|
|
23
|
+
q.set('limit', String(o.limit));
|
|
24
|
+
if (o.cursor)
|
|
25
|
+
q.set('cursor', o.cursor);
|
|
26
|
+
q.set('sort', sortWire[o.sort ?? 'path'] ?? 'path');
|
|
27
|
+
q.set('order', o.descending ? 'desc' : 'asc');
|
|
28
|
+
return q.toString();
|
|
29
|
+
}
|
|
30
|
+
const str = (v) => (typeof v === 'string' && v !== '' ? v : null);
|
|
31
|
+
function fileInfoFromJson(j) {
|
|
32
|
+
const path = String(j.path ?? '');
|
|
33
|
+
const metadata = {};
|
|
34
|
+
if (j.metadata && typeof j.metadata === 'object') {
|
|
35
|
+
for (const [k, v] of Object.entries(j.metadata)) {
|
|
36
|
+
metadata[k] = typeof v === 'string' ? v : String(v);
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
return {
|
|
40
|
+
path,
|
|
41
|
+
name: path.split('/').pop() ?? path,
|
|
42
|
+
size: Number(j.size ?? 0),
|
|
43
|
+
contentType: str(j.content_type),
|
|
44
|
+
etag: str(j.etag),
|
|
45
|
+
metadata,
|
|
46
|
+
versionId: str(j.version_id),
|
|
47
|
+
uploadedBy: str(j.uploaded_by),
|
|
48
|
+
createdAt: String(j.created_at ?? ''),
|
|
49
|
+
updatedAt: String(j.updated_at ?? ''),
|
|
50
|
+
publicUrl: str(j.public_url),
|
|
51
|
+
};
|
|
52
|
+
}
|
|
53
|
+
function filePageFromJson(j) {
|
|
54
|
+
const files = Array.isArray(j.files) ? j.files : [];
|
|
55
|
+
const nextCursor = str(j.next_cursor);
|
|
56
|
+
return {
|
|
57
|
+
files: files.map((f) => fileInfoFromJson(f)),
|
|
58
|
+
nextCursor,
|
|
59
|
+
hasMore: nextCursor !== null,
|
|
60
|
+
};
|
|
61
|
+
}
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
import type { UploadResult } from './types.js';
|
|
2
|
+
/** Where an upload is. */
|
|
3
|
+
export type KoolbaseUploadState =
|
|
4
|
+
/** Not started: asking the server for an upload link. */
|
|
5
|
+
'pending'
|
|
6
|
+
/** Sending the file's bytes; see `bytesSent`. */
|
|
7
|
+
| 'uploading'
|
|
8
|
+
/** The bytes have arrived; the server is checking them and putting the file in place. It can no longer be cancelled. */
|
|
9
|
+
| 'verifying'
|
|
10
|
+
/** Done: the file is in the bucket. */
|
|
11
|
+
| 'completed'
|
|
12
|
+
/** It failed; `error` says why. */
|
|
13
|
+
| 'failed'
|
|
14
|
+
/** Cancelled before the server began checking it. Nothing was stored. */
|
|
15
|
+
| 'cancelled';
|
|
16
|
+
/** One moment of an upload. */
|
|
17
|
+
export interface KoolbaseUploadProgress {
|
|
18
|
+
state: KoolbaseUploadState;
|
|
19
|
+
/** Bytes sent so far. */
|
|
20
|
+
bytesSent: number;
|
|
21
|
+
bytesTotal: number;
|
|
22
|
+
/** 0 to 1: the share of bytes sent; 1 once verifying. */
|
|
23
|
+
fraction: number;
|
|
24
|
+
/** Whether the upload has ended, one way or another. */
|
|
25
|
+
isDone: boolean;
|
|
26
|
+
/** Why it failed, when `state` is `'failed'`. */
|
|
27
|
+
error?: Error;
|
|
28
|
+
}
|
|
29
|
+
/** A running upload: watch it with `onProgress`, `cancel` it, await `result`. */
|
|
30
|
+
export declare class KoolbaseUploadTask {
|
|
31
|
+
private _current;
|
|
32
|
+
private listeners;
|
|
33
|
+
private cancelRequested;
|
|
34
|
+
private abortTransfer;
|
|
35
|
+
private total;
|
|
36
|
+
/**
|
|
37
|
+
* The uploaded file. Rejects with `KoolbaseUploadCancelledError` if it was
|
|
38
|
+
* cancelled, or the error that made it fail.
|
|
39
|
+
*/
|
|
40
|
+
readonly result: Promise<UploadResult>;
|
|
41
|
+
private resolve;
|
|
42
|
+
private reject;
|
|
43
|
+
/** @internal */
|
|
44
|
+
constructor();
|
|
45
|
+
/** Where the upload is now. */
|
|
46
|
+
get current(): KoolbaseUploadProgress;
|
|
47
|
+
/**
|
|
48
|
+
* Calls `listener` on every change of state and every chunk sent, starting
|
|
49
|
+
* with where the upload is now. Returns a function that stops it.
|
|
50
|
+
*/
|
|
51
|
+
onProgress(listener: (p: KoolbaseUploadProgress) => void): () => void;
|
|
52
|
+
/**
|
|
53
|
+
* Stops the upload, if the server has not begun checking it yet. Returns
|
|
54
|
+
* whether it was stopped: false once verifying (the file will land, or
|
|
55
|
+
* fail on its own) or done.
|
|
56
|
+
*/
|
|
57
|
+
cancel(): boolean;
|
|
58
|
+
/** @internal */
|
|
59
|
+
get cancelled(): boolean;
|
|
60
|
+
/** @internal Throws if the upload was cancelled, between steps. */
|
|
61
|
+
checkCancelled(): void;
|
|
62
|
+
/** @internal */
|
|
63
|
+
setTotal(total: number): void;
|
|
64
|
+
/** @internal */
|
|
65
|
+
setAbort(abort: (() => void) | null): void;
|
|
66
|
+
/** @internal */
|
|
67
|
+
emit(state: KoolbaseUploadState, sent?: number, error?: Error): void;
|
|
68
|
+
/** @internal Marks the bytes sent: from here the upload cannot be cancelled. */
|
|
69
|
+
verifying(): void;
|
|
70
|
+
/** @internal */
|
|
71
|
+
finish(result: UploadResult): void;
|
|
72
|
+
/** @internal */
|
|
73
|
+
fail(error: unknown): void;
|
|
74
|
+
}
|
|
75
|
+
/** Runs `body` as the task's upload, starting on the next turn so a caller can listen to every event. */
|
|
76
|
+
export declare function runUploadTask(body: (task: KoolbaseUploadTask) => Promise<UploadResult>): KoolbaseUploadTask;
|
|
77
|
+
interface PutResult {
|
|
78
|
+
status: number;
|
|
79
|
+
etag: string;
|
|
80
|
+
}
|
|
81
|
+
/**
|
|
82
|
+
* Sends `body` to a presigned `url` with PUT, reporting bytes as they are
|
|
83
|
+
* sent. XMLHttpRequest where the host has it (browsers and React Native,
|
|
84
|
+
* both report upload progress); fetch elsewhere, where progress jumps from
|
|
85
|
+
* 0 to the total. A cancel aborts it.
|
|
86
|
+
*/
|
|
87
|
+
export declare function putWithProgress(task: KoolbaseUploadTask, url: string, body: Blob, contentType: string): Promise<PutResult>;
|
|
88
|
+
export {};
|
|
@@ -0,0 +1,214 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
// An upload's lifecycle, as an app watches it (S1).
|
|
3
|
+
//
|
|
4
|
+
// pending -> uploading (bytes sent of total) -> verifying -> completed, or
|
|
5
|
+
// failed / cancelled. Verifying is its own phase: the bytes have arrived and
|
|
6
|
+
// the server is checking them (size, type, the bucket's rules and cap) and
|
|
7
|
+
// putting them in place. Only completed means the file can be referenced
|
|
8
|
+
// from a record.
|
|
9
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
10
|
+
exports.KoolbaseUploadTask = void 0;
|
|
11
|
+
exports.runUploadTask = runUploadTask;
|
|
12
|
+
exports.putWithProgress = putWithProgress;
|
|
13
|
+
const network_js_1 = require("./network.js");
|
|
14
|
+
const storage_errors_js_1 = require("./storage-errors.js");
|
|
15
|
+
function progressOf(state, bytesSent, bytesTotal, error) {
|
|
16
|
+
let fraction;
|
|
17
|
+
if (state === 'verifying' || state === 'completed')
|
|
18
|
+
fraction = 1;
|
|
19
|
+
else if (bytesTotal <= 0)
|
|
20
|
+
fraction = 0;
|
|
21
|
+
else
|
|
22
|
+
fraction = Math.min(1, Math.max(0, bytesSent / bytesTotal));
|
|
23
|
+
return {
|
|
24
|
+
state,
|
|
25
|
+
bytesSent,
|
|
26
|
+
bytesTotal,
|
|
27
|
+
fraction,
|
|
28
|
+
isDone: state === 'completed' || state === 'failed' || state === 'cancelled',
|
|
29
|
+
...(error ? { error } : {}),
|
|
30
|
+
};
|
|
31
|
+
}
|
|
32
|
+
/** A running upload: watch it with `onProgress`, `cancel` it, await `result`. */
|
|
33
|
+
class KoolbaseUploadTask {
|
|
34
|
+
/** @internal */
|
|
35
|
+
constructor() {
|
|
36
|
+
this.listeners = new Set();
|
|
37
|
+
this.cancelRequested = false;
|
|
38
|
+
this.abortTransfer = null;
|
|
39
|
+
this.total = 0;
|
|
40
|
+
this._current = progressOf('pending', 0, 0);
|
|
41
|
+
this.result = new Promise((res, rej) => {
|
|
42
|
+
this.resolve = res;
|
|
43
|
+
this.reject = rej;
|
|
44
|
+
});
|
|
45
|
+
// An app that only listens to progress is not left with an unhandled
|
|
46
|
+
// rejection; awaiting `result` still sees the error.
|
|
47
|
+
this.result.catch(() => undefined);
|
|
48
|
+
}
|
|
49
|
+
/** Where the upload is now. */
|
|
50
|
+
get current() {
|
|
51
|
+
return this._current;
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* Calls `listener` on every change of state and every chunk sent, starting
|
|
55
|
+
* with where the upload is now. Returns a function that stops it.
|
|
56
|
+
*/
|
|
57
|
+
onProgress(listener) {
|
|
58
|
+
this.listeners.add(listener);
|
|
59
|
+
listener(this._current);
|
|
60
|
+
return () => {
|
|
61
|
+
this.listeners.delete(listener);
|
|
62
|
+
};
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* Stops the upload, if the server has not begun checking it yet. Returns
|
|
66
|
+
* whether it was stopped: false once verifying (the file will land, or
|
|
67
|
+
* fail on its own) or done.
|
|
68
|
+
*/
|
|
69
|
+
cancel() {
|
|
70
|
+
if (this._current.isDone || this._current.state === 'verifying')
|
|
71
|
+
return false;
|
|
72
|
+
this.cancelRequested = true;
|
|
73
|
+
this.abortTransfer?.();
|
|
74
|
+
return true;
|
|
75
|
+
}
|
|
76
|
+
/** @internal */
|
|
77
|
+
get cancelled() {
|
|
78
|
+
return this.cancelRequested;
|
|
79
|
+
}
|
|
80
|
+
/** @internal Throws if the upload was cancelled, between steps. */
|
|
81
|
+
checkCancelled() {
|
|
82
|
+
if (this.cancelRequested)
|
|
83
|
+
throw new storage_errors_js_1.KoolbaseUploadCancelledError();
|
|
84
|
+
}
|
|
85
|
+
/** @internal */
|
|
86
|
+
setTotal(total) {
|
|
87
|
+
this.total = total;
|
|
88
|
+
}
|
|
89
|
+
/** @internal */
|
|
90
|
+
setAbort(abort) {
|
|
91
|
+
this.abortTransfer = abort;
|
|
92
|
+
}
|
|
93
|
+
/** @internal */
|
|
94
|
+
emit(state, sent, error) {
|
|
95
|
+
if (this._current.isDone)
|
|
96
|
+
return;
|
|
97
|
+
this._current = progressOf(state, sent ?? this._current.bytesSent, this.total, error);
|
|
98
|
+
for (const l of [...this.listeners]) {
|
|
99
|
+
try {
|
|
100
|
+
l(this._current);
|
|
101
|
+
}
|
|
102
|
+
catch {
|
|
103
|
+
// A listener's own failure is not the upload's.
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
/** @internal Marks the bytes sent: from here the upload cannot be cancelled. */
|
|
108
|
+
verifying() {
|
|
109
|
+
this.checkCancelled();
|
|
110
|
+
this.emit('verifying', this.total);
|
|
111
|
+
}
|
|
112
|
+
/** @internal */
|
|
113
|
+
finish(result) {
|
|
114
|
+
this.emit('completed', this.total);
|
|
115
|
+
this.listeners.clear();
|
|
116
|
+
this.resolve(result);
|
|
117
|
+
}
|
|
118
|
+
/** @internal */
|
|
119
|
+
fail(error) {
|
|
120
|
+
if (this.cancelRequested) {
|
|
121
|
+
const e = new storage_errors_js_1.KoolbaseUploadCancelledError();
|
|
122
|
+
this.emit('cancelled');
|
|
123
|
+
this.reject(e);
|
|
124
|
+
}
|
|
125
|
+
else {
|
|
126
|
+
const e = error instanceof Error ? error : new storage_errors_js_1.KoolbaseStorageError(String(error));
|
|
127
|
+
this.emit('failed', undefined, e);
|
|
128
|
+
this.reject(e);
|
|
129
|
+
}
|
|
130
|
+
this.listeners.clear();
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
exports.KoolbaseUploadTask = KoolbaseUploadTask;
|
|
134
|
+
/** Runs `body` as the task's upload, starting on the next turn so a caller can listen to every event. */
|
|
135
|
+
function runUploadTask(body) {
|
|
136
|
+
const task = new KoolbaseUploadTask();
|
|
137
|
+
Promise.resolve().then(async () => {
|
|
138
|
+
try {
|
|
139
|
+
task.finish(await body(task));
|
|
140
|
+
}
|
|
141
|
+
catch (e) {
|
|
142
|
+
task.fail(e);
|
|
143
|
+
}
|
|
144
|
+
});
|
|
145
|
+
return task;
|
|
146
|
+
}
|
|
147
|
+
/**
|
|
148
|
+
* Sends `body` to a presigned `url` with PUT, reporting bytes as they are
|
|
149
|
+
* sent. XMLHttpRequest where the host has it (browsers and React Native,
|
|
150
|
+
* both report upload progress); fetch elsewhere, where progress jumps from
|
|
151
|
+
* 0 to the total. A cancel aborts it.
|
|
152
|
+
*/
|
|
153
|
+
function putWithProgress(task, url, body, contentType) {
|
|
154
|
+
task.checkCancelled();
|
|
155
|
+
const total = body.size;
|
|
156
|
+
const report = (sent) => {
|
|
157
|
+
if (!task.cancelled)
|
|
158
|
+
task.emit('uploading', Math.min(sent, total));
|
|
159
|
+
};
|
|
160
|
+
report(0);
|
|
161
|
+
const XHR = globalThis.XMLHttpRequest;
|
|
162
|
+
if (XHR) {
|
|
163
|
+
return new Promise((resolve, reject) => {
|
|
164
|
+
const xhr = new XHR();
|
|
165
|
+
let settled = false;
|
|
166
|
+
const done = (fn) => {
|
|
167
|
+
if (settled)
|
|
168
|
+
return;
|
|
169
|
+
settled = true;
|
|
170
|
+
task.setAbort(null);
|
|
171
|
+
fn();
|
|
172
|
+
};
|
|
173
|
+
xhr.open('PUT', url);
|
|
174
|
+
xhr.setRequestHeader('Content-Type', contentType);
|
|
175
|
+
if (xhr.upload) {
|
|
176
|
+
xhr.upload.onprogress = (ev) => report(ev.loaded);
|
|
177
|
+
}
|
|
178
|
+
xhr.onload = () => done(() => {
|
|
179
|
+
if (task.cancelled)
|
|
180
|
+
return reject(new storage_errors_js_1.KoolbaseUploadCancelledError());
|
|
181
|
+
resolve({ status: xhr.status, etag: xhr.getResponseHeader('etag') ?? '' });
|
|
182
|
+
});
|
|
183
|
+
xhr.onerror = () => done(() => reject(task.cancelled ? new storage_errors_js_1.KoolbaseUploadCancelledError() : new network_js_1.KoolbaseNetworkError(url, new Error('the upload did not complete'))));
|
|
184
|
+
xhr.onabort = () => done(() => reject(new storage_errors_js_1.KoolbaseUploadCancelledError()));
|
|
185
|
+
task.setAbort(() => {
|
|
186
|
+
xhr.abort();
|
|
187
|
+
// Some hosts do not fire onabort for an aborted send.
|
|
188
|
+
done(() => reject(new storage_errors_js_1.KoolbaseUploadCancelledError()));
|
|
189
|
+
});
|
|
190
|
+
xhr.send(body);
|
|
191
|
+
});
|
|
192
|
+
}
|
|
193
|
+
const controller = typeof AbortController !== 'undefined' ? new AbortController() : null;
|
|
194
|
+
task.setAbort(() => controller?.abort());
|
|
195
|
+
return fetch(url, {
|
|
196
|
+
method: 'PUT',
|
|
197
|
+
headers: { 'Content-Type': contentType },
|
|
198
|
+
body,
|
|
199
|
+
signal: controller?.signal,
|
|
200
|
+
})
|
|
201
|
+
.then((res) => {
|
|
202
|
+
task.checkCancelled();
|
|
203
|
+
return { status: res.status, etag: res.headers.get('etag') ?? '' };
|
|
204
|
+
})
|
|
205
|
+
.catch((e) => {
|
|
206
|
+
if (task.cancelled || e?.name === 'AbortError') {
|
|
207
|
+
throw new storage_errors_js_1.KoolbaseUploadCancelledError();
|
|
208
|
+
}
|
|
209
|
+
if (e instanceof storage_errors_js_1.KoolbaseStorageError)
|
|
210
|
+
throw e;
|
|
211
|
+
throw new network_js_1.KoolbaseNetworkError(url, e);
|
|
212
|
+
})
|
|
213
|
+
.finally(() => task.setAbort(null));
|
|
214
|
+
}
|
package/dist/cjs/storage.d.ts
CHANGED
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
import { KoolbaseConfig, UploadOptions, UploadResult, KoolbaseObject, KoolbaseObjectVersion, KoolbaseImageTransform } from './types.js';
|
|
2
|
+
import { KoolbaseUploadTask } from './storage-transfer.js';
|
|
3
|
+
import { KoolbaseFileInfo, KoolbaseFilePage, ListFilesOptions } from './storage-files.js';
|
|
2
4
|
/**
|
|
3
5
|
* Koolbase storage client — uploads, downloads, and deletes via presigned
|
|
4
6
|
* Cloudflare R2 URLs.
|
|
@@ -53,6 +55,45 @@ export declare class KoolbaseStorage {
|
|
|
53
55
|
* overwriting silently, pass `overwrite: true` explicitly.
|
|
54
56
|
*/
|
|
55
57
|
upload(options: UploadOptions): Promise<UploadResult>;
|
|
58
|
+
/**
|
|
59
|
+
* Starts an upload you can follow and cancel: the same upload as
|
|
60
|
+
* {@link upload}, returned at once as a {@link KoolbaseUploadTask}.
|
|
61
|
+
*
|
|
62
|
+
* The task goes pending -> uploading (bytes sent of total) -> verifying
|
|
63
|
+
* -> completed, or failed / cancelled. `cancel()` stops it until the
|
|
64
|
+
* server begins checking the bytes (verifying); nothing is stored. Only
|
|
65
|
+
* completed means the file can be referenced from a record.
|
|
66
|
+
*
|
|
67
|
+
* @example
|
|
68
|
+
* const task = Koolbase.storage.startUpload({ bucket: 'posters', path: 'gig.png', file });
|
|
69
|
+
* const stop = task.onProgress((p) => setPercent(Math.round(p.fraction * 100)));
|
|
70
|
+
* cancelButton.onclick = () => task.cancel();
|
|
71
|
+
* const { object } = await task.result;
|
|
72
|
+
*/
|
|
73
|
+
startUpload(options: UploadOptions): KoolbaseUploadTask;
|
|
74
|
+
private runUpload;
|
|
75
|
+
/**
|
|
76
|
+
* One page of a bucket's files. The bucket's view rule is applied to every
|
|
77
|
+
* file: the page holds only files the signed-in person may view. Pass the
|
|
78
|
+
* page's `nextCursor` back as `cursor` for the next one; a page can hold
|
|
79
|
+
* fewer files than `limit` and still have a next.
|
|
80
|
+
*
|
|
81
|
+
* @example
|
|
82
|
+
* let cursor: string | undefined;
|
|
83
|
+
* do {
|
|
84
|
+
* const page = await Koolbase.storage.listFiles({ bucket: 'posters', prefix: 'events/', cursor });
|
|
85
|
+
* show(page.files);
|
|
86
|
+
* cursor = page.nextCursor ?? undefined;
|
|
87
|
+
* } while (cursor);
|
|
88
|
+
*/
|
|
89
|
+
listFiles(options: ListFilesOptions): Promise<KoolbaseFilePage>;
|
|
90
|
+
/**
|
|
91
|
+
* One file's details -- size, type, metadata, who uploaded it, and its
|
|
92
|
+
* permanent link while its bucket is public. Throws
|
|
93
|
+
* `KoolbaseStorageNotFoundError` for a file that is not there or that
|
|
94
|
+
* the bucket's view rule hides from the caller.
|
|
95
|
+
*/
|
|
96
|
+
getFileInfo(bucket: string, path: string): Promise<KoolbaseFileInfo>;
|
|
56
97
|
/**
|
|
57
98
|
* Apply a partial metadata update to an existing object. Returns the
|
|
58
99
|
* post-update {@link KoolbaseObject} with the merged metadata.
|