@techfinityedge/koolbase-react-native 5.0.0 → 5.1.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/README.md +59 -18
- package/dist/storage-errors.d.ts +46 -1
- package/dist/storage-errors.js +74 -4
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -322,24 +322,64 @@ try {
|
|
|
322
322
|
path: filename,
|
|
323
323
|
file: { uri, name: filename, type: mimeType },
|
|
324
324
|
});
|
|
325
|
+
} catch (e) catch (e) {
|
|
326
|
+
if (e instanceof KoolbaseStorageConflictError) {
|
|
327
|
+
const ok = await confirm(${e.path} already exists. Overwrite?);
|
|
328
|
+
if (ok) {
|
|
329
|
+
await Koolbase.storage.upload({
|
|
330
|
+
bucket: 'documents',
|
|
331
|
+
path: filename,
|
|
332
|
+
file: { uri, name: filename, type: mimeType },
|
|
333
|
+
overwrite: true,
|
|
334
|
+
});
|
|
335
|
+
}
|
|
336
|
+
} else {
|
|
337
|
+
throw e;
|
|
338
|
+
}
|
|
339
|
+
}
|
|
340
|
+
```
|
|
341
|
+
|
|
342
|
+
See [Error handling](#error-handling) for the full set of storage errors.
|
|
343
|
+
|
|
344
|
+
---
|
|
345
|
+
|
|
346
|
+
### Handling bucket limits
|
|
347
|
+
|
|
348
|
+
Buckets can be configured at creation time with a total size cap
|
|
349
|
+
(`max_size_bytes`), a per-file cap (`max_file_size_bytes`), and a
|
|
350
|
+
content-type allowlist (`allowed_mime_types`, supports `image/*`-style
|
|
351
|
+
wildcards). The server surfaces violations as typed errors:
|
|
352
|
+
|
|
353
|
+
````typescript
|
|
354
|
+
import {
|
|
355
|
+
KoolbaseStorageQuotaError,
|
|
356
|
+
KoolbaseStorageFileTooLargeError,
|
|
357
|
+
KoolbaseStorageMimeTypeError,
|
|
358
|
+
} from '@techfinityedge/koolbase-react-native';
|
|
359
|
+
|
|
360
|
+
try {
|
|
361
|
+
await Koolbase.storage.upload({
|
|
362
|
+
bucket: 'user-photos',
|
|
363
|
+
path: filename,
|
|
364
|
+
file: { uri, name: filename, type: mimeType },
|
|
365
|
+
});
|
|
325
366
|
} catch (e) {
|
|
326
|
-
if (e instanceof
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
file: { uri, name: filename, type: mimeType },
|
|
333
|
-
overwrite: true,
|
|
334
|
-
});
|
|
335
|
-
}
|
|
367
|
+
if (e instanceof KoolbaseStorageMimeTypeError) {
|
|
368
|
+
showError('That file type is not allowed in this bucket.');
|
|
369
|
+
} else if (e instanceof KoolbaseStorageFileTooLargeError) {
|
|
370
|
+
showError('That file is too big — pick a smaller one.');
|
|
371
|
+
} else if (e instanceof KoolbaseStorageQuotaError) {
|
|
372
|
+
showError('This bucket is full — delete some files and try again.');
|
|
336
373
|
} else {
|
|
337
374
|
throw e;
|
|
338
375
|
}
|
|
339
376
|
}
|
|
340
|
-
|
|
377
|
+
````
|
|
341
378
|
|
|
342
|
-
|
|
379
|
+
MIME enforcement runs at presign time — no bytes are transferred before
|
|
380
|
+
rejection. File-size and quota enforcement run at confirm time; the
|
|
381
|
+
server cleans up the underlying R2 object before returning the error,
|
|
382
|
+
so nothing leaks.
|
|
343
383
|
|
|
344
384
|
---
|
|
345
385
|
|
|
@@ -555,12 +595,13 @@ handling doesn't depend on message text.
|
|
|
555
595
|
All data-layer failures extend `KoolbaseDataError` (which extends `Error`):
|
|
556
596
|
|
|
557
597
|
| Error | When |
|
|
558
|
-
|
|
559
|
-
| `
|
|
560
|
-
| `
|
|
561
|
-
| `
|
|
562
|
-
| `
|
|
563
|
-
| `
|
|
598
|
+
| `KoolbaseStorageConflictError` | An upload targets a path that's already taken and `overwrite: false` (409, code `PATH_CONFLICT`). Exposes `.path` — the colliding path. |
|
|
599
|
+
| `KoolbaseStorageNotFoundError` | The bucket or object doesn't exist (404). |
|
|
600
|
+
| `KoolbaseStorageValidationError` | The request was rejected as invalid — bad path, missing field (400). |
|
|
601
|
+
| `KoolbaseStoragePermissionError` | The caller is not allowed to perform the operation (403). |
|
|
602
|
+
| `KoolbaseStorageQuotaError` | An upload would push the bucket past its `max_size_bytes` cap (409, code `QUOTA_EXCEEDED`). |
|
|
603
|
+
| `KoolbaseStorageFileTooLargeError` | A single file exceeds the bucket's `max_file_size_bytes` cap (413, code `FILE_TOO_LARGE`). |
|
|
604
|
+
| `KoolbaseStorageMimeTypeError` | The upload's content-type isn't in the bucket's `allowed_mime_types` allowlist (415, code `MIME_NOT_ALLOWED`). |
|
|
564
605
|
|
|
565
606
|
```ts
|
|
566
607
|
import { KoolbaseConflictError, KoolbaseDataError } from '@techfinityedge/koolbase-react-native';
|
package/dist/storage-errors.d.ts
CHANGED
|
@@ -10,7 +10,7 @@ export declare class KoolbaseStorageError extends Error {
|
|
|
10
10
|
/**
|
|
11
11
|
* Thrown when an upload is rejected because an object already exists at
|
|
12
12
|
* the requested path — the server responds with 409 Conflict and code
|
|
13
|
-
* `
|
|
13
|
+
* `path_conflict`. Catch it to give the user an "overwrite this file?"
|
|
14
14
|
* prompt, then retry the upload with `overwrite: true`.
|
|
15
15
|
*
|
|
16
16
|
* `path` is the colliding path the server rejected, surfaced from the
|
|
@@ -64,11 +64,56 @@ export declare class KoolbaseStorageValidationError extends KoolbaseStorageError
|
|
|
64
64
|
export declare class KoolbaseStoragePermissionError extends KoolbaseStorageError {
|
|
65
65
|
constructor(message?: string);
|
|
66
66
|
}
|
|
67
|
+
/**
|
|
68
|
+
* Thrown when an upload would push the bucket past its configured
|
|
69
|
+
* `max_size_bytes` quota — the server responds with 409 Conflict and code
|
|
70
|
+
* `quota_exceeded`. The server cleans up the underlying R2 object before
|
|
71
|
+
* returning; nothing leaks. Catch this to surface a "bucket is full"
|
|
72
|
+
* message or prompt the caller to delete older files. The per-bucket
|
|
73
|
+
* quota is set at bucket creation time and is currently immutable.
|
|
74
|
+
*
|
|
75
|
+
* Distinct from {@link KoolbaseStorageConflictError} (which also uses
|
|
76
|
+
* 409 but means "path collides"); branch on the error type via
|
|
77
|
+
* `instanceof`, not on status.
|
|
78
|
+
*/
|
|
79
|
+
export declare class KoolbaseStorageQuotaError extends KoolbaseStorageError {
|
|
80
|
+
constructor(message?: string);
|
|
81
|
+
}
|
|
82
|
+
/**
|
|
83
|
+
* Thrown when a single file exceeds the bucket's configured
|
|
84
|
+
* `max_file_size_bytes` — the server responds with 413 Payload Too Large
|
|
85
|
+
* and code `file_too_large`. The server cleans up the underlying R2
|
|
86
|
+
* object before returning. The configured per-file limit lives on the
|
|
87
|
+
* bucket record; check `Bucket.maxFileSizeBytes` to surface a clear
|
|
88
|
+
* "files must be under X MB" message at the call site.
|
|
89
|
+
*/
|
|
90
|
+
export declare class KoolbaseStorageFileTooLargeError extends KoolbaseStorageError {
|
|
91
|
+
constructor(message?: string);
|
|
92
|
+
}
|
|
93
|
+
/**
|
|
94
|
+
* Thrown when an upload's content-type isn't in the bucket's configured
|
|
95
|
+
* `allowed_mime_types` allowlist — the server responds with 415
|
|
96
|
+
* Unsupported Media Type and code `mime_not_allowed`. The check runs at
|
|
97
|
+
* presign time, so no bytes are transferred before rejection.
|
|
98
|
+
*
|
|
99
|
+
* Allowlists support `type/*` wildcards (e.g. `image/*` matches every
|
|
100
|
+
* image content-type). A bucket with no allowlist configured accepts
|
|
101
|
+
* every type.
|
|
102
|
+
*/
|
|
103
|
+
export declare class KoolbaseStorageMimeTypeError extends KoolbaseStorageError {
|
|
104
|
+
constructor(message?: string);
|
|
105
|
+
}
|
|
67
106
|
/**
|
|
68
107
|
* Maps a non-2xx storage-layer response to a typed
|
|
69
108
|
* {@link KoolbaseStorageError}, preferring the server's stable `code` and
|
|
70
109
|
* falling back to the HTTP status for older or uncoded responses. Always
|
|
71
110
|
* returns an error to throw.
|
|
111
|
+
*
|
|
112
|
+
* Status-fallback note: HTTP 409 covers both path_conflict and
|
|
113
|
+
* quota_exceeded. Without a `code` field, the mapper defaults 409 to
|
|
114
|
+
* {@link KoolbaseStorageConflictError} since path collisions are the more
|
|
115
|
+
* common case. Modern Koolbase servers always emit `code`, so this only
|
|
116
|
+
* matters for very old API responses or non-Koolbase 409s.
|
|
72
117
|
*/
|
|
73
118
|
export declare function koolbaseStorageError(status: number, body: any, fallbackMessage?: string): KoolbaseStorageError;
|
|
74
119
|
/**
|
package/dist/storage-errors.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.KoolbaseStoragePermissionError = exports.KoolbaseStorageValidationError = exports.KoolbaseStorageNotFoundError = exports.KoolbaseStorageConflictError = exports.KoolbaseStorageError = void 0;
|
|
3
|
+
exports.KoolbaseStorageMimeTypeError = exports.KoolbaseStorageFileTooLargeError = exports.KoolbaseStorageQuotaError = exports.KoolbaseStoragePermissionError = exports.KoolbaseStorageValidationError = exports.KoolbaseStorageNotFoundError = exports.KoolbaseStorageConflictError = exports.KoolbaseStorageError = void 0;
|
|
4
4
|
exports.koolbaseStorageError = koolbaseStorageError;
|
|
5
5
|
exports.koolbaseStorageErrorFromResponse = koolbaseStorageErrorFromResponse;
|
|
6
6
|
/**
|
|
@@ -20,7 +20,7 @@ exports.KoolbaseStorageError = KoolbaseStorageError;
|
|
|
20
20
|
/**
|
|
21
21
|
* Thrown when an upload is rejected because an object already exists at
|
|
22
22
|
* the requested path — the server responds with 409 Conflict and code
|
|
23
|
-
* `
|
|
23
|
+
* `path_conflict`. Catch it to give the user an "overwrite this file?"
|
|
24
24
|
* prompt, then retry the upload with `overwrite: true`.
|
|
25
25
|
*
|
|
26
26
|
* `path` is the colliding path the server rejected, surfaced from the
|
|
@@ -49,7 +49,7 @@ exports.KoolbaseStorageError = KoolbaseStorageError;
|
|
|
49
49
|
*/
|
|
50
50
|
class KoolbaseStorageConflictError extends KoolbaseStorageError {
|
|
51
51
|
constructor(message, path) {
|
|
52
|
-
super(message ?? 'An object already exists at this path', '
|
|
52
|
+
super(message ?? 'An object already exists at this path', 'path_conflict');
|
|
53
53
|
this.path = path;
|
|
54
54
|
this.name = 'KoolbaseStorageConflictError';
|
|
55
55
|
Object.setPrototypeOf(this, KoolbaseStorageConflictError.prototype);
|
|
@@ -94,24 +94,94 @@ class KoolbaseStoragePermissionError extends KoolbaseStorageError {
|
|
|
94
94
|
}
|
|
95
95
|
}
|
|
96
96
|
exports.KoolbaseStoragePermissionError = KoolbaseStoragePermissionError;
|
|
97
|
+
/**
|
|
98
|
+
* Thrown when an upload would push the bucket past its configured
|
|
99
|
+
* `max_size_bytes` quota — the server responds with 409 Conflict and code
|
|
100
|
+
* `quota_exceeded`. The server cleans up the underlying R2 object before
|
|
101
|
+
* returning; nothing leaks. Catch this to surface a "bucket is full"
|
|
102
|
+
* message or prompt the caller to delete older files. The per-bucket
|
|
103
|
+
* quota is set at bucket creation time and is currently immutable.
|
|
104
|
+
*
|
|
105
|
+
* Distinct from {@link KoolbaseStorageConflictError} (which also uses
|
|
106
|
+
* 409 but means "path collides"); branch on the error type via
|
|
107
|
+
* `instanceof`, not on status.
|
|
108
|
+
*/
|
|
109
|
+
class KoolbaseStorageQuotaError extends KoolbaseStorageError {
|
|
110
|
+
constructor(message) {
|
|
111
|
+
super(message ?? 'Bucket quota exceeded', 'quota_exceeded');
|
|
112
|
+
this.name = 'KoolbaseStorageQuotaError';
|
|
113
|
+
Object.setPrototypeOf(this, KoolbaseStorageQuotaError.prototype);
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
exports.KoolbaseStorageQuotaError = KoolbaseStorageQuotaError;
|
|
117
|
+
/**
|
|
118
|
+
* Thrown when a single file exceeds the bucket's configured
|
|
119
|
+
* `max_file_size_bytes` — the server responds with 413 Payload Too Large
|
|
120
|
+
* and code `file_too_large`. The server cleans up the underlying R2
|
|
121
|
+
* object before returning. The configured per-file limit lives on the
|
|
122
|
+
* bucket record; check `Bucket.maxFileSizeBytes` to surface a clear
|
|
123
|
+
* "files must be under X MB" message at the call site.
|
|
124
|
+
*/
|
|
125
|
+
class KoolbaseStorageFileTooLargeError extends KoolbaseStorageError {
|
|
126
|
+
constructor(message) {
|
|
127
|
+
super(message ?? 'File exceeds the bucket maximum file size', 'file_too_large');
|
|
128
|
+
this.name = 'KoolbaseStorageFileTooLargeError';
|
|
129
|
+
Object.setPrototypeOf(this, KoolbaseStorageFileTooLargeError.prototype);
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
exports.KoolbaseStorageFileTooLargeError = KoolbaseStorageFileTooLargeError;
|
|
133
|
+
/**
|
|
134
|
+
* Thrown when an upload's content-type isn't in the bucket's configured
|
|
135
|
+
* `allowed_mime_types` allowlist — the server responds with 415
|
|
136
|
+
* Unsupported Media Type and code `mime_not_allowed`. The check runs at
|
|
137
|
+
* presign time, so no bytes are transferred before rejection.
|
|
138
|
+
*
|
|
139
|
+
* Allowlists support `type/*` wildcards (e.g. `image/*` matches every
|
|
140
|
+
* image content-type). A bucket with no allowlist configured accepts
|
|
141
|
+
* every type.
|
|
142
|
+
*/
|
|
143
|
+
class KoolbaseStorageMimeTypeError extends KoolbaseStorageError {
|
|
144
|
+
constructor(message) {
|
|
145
|
+
super(message ?? 'Content-type not allowed for this bucket', 'mime_not_allowed');
|
|
146
|
+
this.name = 'KoolbaseStorageMimeTypeError';
|
|
147
|
+
Object.setPrototypeOf(this, KoolbaseStorageMimeTypeError.prototype);
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
exports.KoolbaseStorageMimeTypeError = KoolbaseStorageMimeTypeError;
|
|
97
151
|
/**
|
|
98
152
|
* Maps a non-2xx storage-layer response to a typed
|
|
99
153
|
* {@link KoolbaseStorageError}, preferring the server's stable `code` and
|
|
100
154
|
* falling back to the HTTP status for older or uncoded responses. Always
|
|
101
155
|
* returns an error to throw.
|
|
156
|
+
*
|
|
157
|
+
* Status-fallback note: HTTP 409 covers both path_conflict and
|
|
158
|
+
* quota_exceeded. Without a `code` field, the mapper defaults 409 to
|
|
159
|
+
* {@link KoolbaseStorageConflictError} since path collisions are the more
|
|
160
|
+
* common case. Modern Koolbase servers always emit `code`, so this only
|
|
161
|
+
* matters for very old API responses or non-Koolbase 409s.
|
|
102
162
|
*/
|
|
103
163
|
function koolbaseStorageError(status, body, fallbackMessage = 'Storage request failed') {
|
|
104
164
|
const code = body?.code;
|
|
105
165
|
const message = body?.error ?? fallbackMessage;
|
|
106
166
|
// ─── code-first ───
|
|
107
167
|
switch (code) {
|
|
108
|
-
case '
|
|
168
|
+
case 'path_conflict':
|
|
109
169
|
return new KoolbaseStorageConflictError(message, body?.path);
|
|
170
|
+
case 'quota_exceeded':
|
|
171
|
+
return new KoolbaseStorageQuotaError(message);
|
|
172
|
+
case 'file_too_large':
|
|
173
|
+
return new KoolbaseStorageFileTooLargeError(message);
|
|
174
|
+
case 'mime_not_allowed':
|
|
175
|
+
return new KoolbaseStorageMimeTypeError(message);
|
|
110
176
|
}
|
|
111
177
|
// ─── status fallback (pre-code servers or uncoded paths) ───
|
|
112
178
|
switch (status) {
|
|
113
179
|
case 409:
|
|
114
180
|
return new KoolbaseStorageConflictError(message);
|
|
181
|
+
case 413:
|
|
182
|
+
return new KoolbaseStorageFileTooLargeError(message);
|
|
183
|
+
case 415:
|
|
184
|
+
return new KoolbaseStorageMimeTypeError(message);
|
|
115
185
|
case 404:
|
|
116
186
|
return new KoolbaseStorageNotFoundError(message);
|
|
117
187
|
case 403:
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@techfinityedge/koolbase-react-native",
|
|
3
|
-
"version": "5.
|
|
3
|
+
"version": "5.1.1",
|
|
4
4
|
"description": "React Native SDK for Koolbase — auth, database, storage, realtime, feature flags, and functions in one package.",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|