@quatrain/storage-supabase 1.1.13 → 1.1.15
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 +28 -0
- package/lib/SupabaseStorageAdapter.d.ts +9 -0
- package/lib/SupabaseStorageAdapter.js +40 -4
- package/package.json +4 -4
package/README.md
ADDED
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
# @quatrain/storage-supabase
|
|
2
|
+
|
|
3
|
+
A storage adapter for Supabase Storage. This package allows Quatrain to use Supabase for S3-compatible object storage.
|
|
4
|
+
|
|
5
|
+
## Features
|
|
6
|
+
|
|
7
|
+
- Implements the `@quatrain/storage` abstract adapter.
|
|
8
|
+
- Works with both Supabase SaaS and self-hosted instances.
|
|
9
|
+
- Integrates with Supabase's policies for fine-grained file access control.
|
|
10
|
+
- Uses the `@supabase/supabase-js` library.
|
|
11
|
+
|
|
12
|
+
## Installation
|
|
13
|
+
|
|
14
|
+
```bash
|
|
15
|
+
npm install @quatrain/storage-supabase @supabase/supabase-js
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
## Usage
|
|
19
|
+
|
|
20
|
+
```typescript
|
|
21
|
+
import { Storage } from '@quatrain/storage'
|
|
22
|
+
import { SupabaseStorageAdapter } from '@quatrain/storage-supabase'
|
|
23
|
+
|
|
24
|
+
const adapter = new SupabaseStorageAdapter({
|
|
25
|
+
config: { url: '...', anonKey: '...' },
|
|
26
|
+
})
|
|
27
|
+
Storage.addAdapter(adapter, 'default', true)
|
|
28
|
+
```
|
|
@@ -11,6 +11,7 @@ export declare class SupabaseStorageAdapter extends AbstractStorageAdapter {
|
|
|
11
11
|
getMetaData(file: FileType): Promise<FileType>;
|
|
12
12
|
test(): Promise<boolean>;
|
|
13
13
|
streamToBuffer(stream: Stream): Promise<Buffer>;
|
|
14
|
+
toArrayBuffer(buffer: Buffer): ArrayBuffer;
|
|
14
15
|
create(file: FileType, stream: Readable | string): Promise<FileType>;
|
|
15
16
|
copy(file: FileType, destFile: FileType): Promise<void>;
|
|
16
17
|
move(file: FileType, destFile: FileType): Promise<FileType>;
|
|
@@ -22,5 +23,13 @@ export declare class SupabaseStorageAdapter extends AbstractStorageAdapter {
|
|
|
22
23
|
getReadable(file: FileType): Promise<Readable>;
|
|
23
24
|
stream(file: FileType, res: any): Promise<any>;
|
|
24
25
|
download(file: FileType, meta: DownloadFileMetaType): Promise<string | Blob>;
|
|
26
|
+
/**
|
|
27
|
+
* Get signed upload url for file
|
|
28
|
+
* Careful, on docker the time to live for JWT signature is defaulted to 60 sec
|
|
29
|
+
* Add SIGNED_UPLOAD_URL_EXPIRATION_TIME env variable to fix TTL
|
|
30
|
+
* @param file FileType
|
|
31
|
+
* @param _expiresIn actually ignored
|
|
32
|
+
* @returns
|
|
33
|
+
*/
|
|
25
34
|
getUploadUrl(file: FileType, _expiresIn?: number): Promise<FileResponseLinkType>;
|
|
26
35
|
}
|
|
@@ -61,12 +61,19 @@ class SupabaseStorageAdapter extends storage_1.AbstractStorageAdapter {
|
|
|
61
61
|
});
|
|
62
62
|
});
|
|
63
63
|
}
|
|
64
|
+
toArrayBuffer(buffer) {
|
|
65
|
+
const arrayBuffer = new ArrayBuffer(buffer.length);
|
|
66
|
+
const view = new Uint8Array(arrayBuffer);
|
|
67
|
+
for (let i = 0; i < buffer.length; ++i) {
|
|
68
|
+
view[i] = buffer[i];
|
|
69
|
+
}
|
|
70
|
+
return arrayBuffer;
|
|
71
|
+
}
|
|
64
72
|
create(file, stream) {
|
|
65
73
|
return __awaiter(this, void 0, void 0, function* () {
|
|
66
|
-
|
|
67
|
-
storage_1.Storage.info(`Uploading ${file.ref} to ${file.bucket}`);
|
|
74
|
+
storage_1.Storage.info(`[SSA] Uploading ${file.ref} to ${file.bucket}`);
|
|
68
75
|
if (typeof stream === 'string') {
|
|
69
|
-
const {
|
|
76
|
+
const { error } = yield this._client
|
|
70
77
|
.from(file.bucket)
|
|
71
78
|
.upload(file.ref, new Blob([node_fs_1.default.readFileSync(stream)]), {
|
|
72
79
|
// cacheControl: '3600',
|
|
@@ -74,6 +81,24 @@ class SupabaseStorageAdapter extends storage_1.AbstractStorageAdapter {
|
|
|
74
81
|
contentType: file.contentType,
|
|
75
82
|
});
|
|
76
83
|
if (error !== null) {
|
|
84
|
+
console.log(error);
|
|
85
|
+
storage_1.Storage.error(`Unable to upload ${file.ref} to ${file.bucket}`);
|
|
86
|
+
throw new Error(`Unable to upload ${file.ref} to ${file.bucket}`);
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
else {
|
|
90
|
+
const content = new Blob([
|
|
91
|
+
this.toArrayBuffer(yield this.streamToBuffer(stream)),
|
|
92
|
+
]);
|
|
93
|
+
const { error } = yield this._client
|
|
94
|
+
.from(file.bucket)
|
|
95
|
+
.upload(file.ref, content, {
|
|
96
|
+
// cacheControl: '3600',
|
|
97
|
+
upsert: false,
|
|
98
|
+
contentType: file.contentType,
|
|
99
|
+
});
|
|
100
|
+
if (error !== null) {
|
|
101
|
+
console.log(error);
|
|
77
102
|
storage_1.Storage.error(`Unable to upload ${file.ref} to ${file.bucket}`);
|
|
78
103
|
throw new Error(`Unable to upload ${file.ref} to ${file.bucket}`);
|
|
79
104
|
}
|
|
@@ -161,7 +186,7 @@ class SupabaseStorageAdapter extends storage_1.AbstractStorageAdapter {
|
|
|
161
186
|
return __awaiter(this, void 0, void 0, function* () {
|
|
162
187
|
const { data, error } = yield this._client
|
|
163
188
|
.from(file.bucket)
|
|
164
|
-
.download(
|
|
189
|
+
.download(file.ref);
|
|
165
190
|
if (error !== null) {
|
|
166
191
|
console.log(error);
|
|
167
192
|
throw new Error(`Unable to download ${file.ref}`);
|
|
@@ -169,9 +194,20 @@ class SupabaseStorageAdapter extends storage_1.AbstractStorageAdapter {
|
|
|
169
194
|
if (meta.onlyContent) {
|
|
170
195
|
return data;
|
|
171
196
|
}
|
|
197
|
+
// Write the downloaded data to the specified path
|
|
198
|
+
const buffer = yield data.arrayBuffer();
|
|
199
|
+
node_fs_1.default.writeFileSync(meta.path, Buffer.from(buffer));
|
|
172
200
|
return meta.path;
|
|
173
201
|
});
|
|
174
202
|
}
|
|
203
|
+
/**
|
|
204
|
+
* Get signed upload url for file
|
|
205
|
+
* Careful, on docker the time to live for JWT signature is defaulted to 60 sec
|
|
206
|
+
* Add SIGNED_UPLOAD_URL_EXPIRATION_TIME env variable to fix TTL
|
|
207
|
+
* @param file FileType
|
|
208
|
+
* @param _expiresIn actually ignored
|
|
209
|
+
* @returns
|
|
210
|
+
*/
|
|
175
211
|
getUploadUrl(file, _expiresIn = 7200) {
|
|
176
212
|
return __awaiter(this, void 0, void 0, function* () {
|
|
177
213
|
const { data, error } = yield this._client
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@quatrain/storage-supabase",
|
|
3
|
-
"version": "1.1.
|
|
3
|
+
"version": "1.1.15",
|
|
4
4
|
"description": "Storage adapter for Supabase Storage",
|
|
5
5
|
"main": "lib/index.js",
|
|
6
6
|
"types": "lib/index.d.ts",
|
|
@@ -22,10 +22,10 @@
|
|
|
22
22
|
"typescript": "^5.1.5"
|
|
23
23
|
},
|
|
24
24
|
"dependencies": {
|
|
25
|
-
"@quatrain/core": "^1.1.
|
|
26
|
-
"@quatrain/storage": "^1.1.
|
|
25
|
+
"@quatrain/core": "^1.1.23",
|
|
26
|
+
"@quatrain/storage": "^1.1.21",
|
|
27
27
|
"@supabase/storage-js": "^2.7.2",
|
|
28
|
-
"@supabase/supabase-js": "^2.
|
|
28
|
+
"@supabase/supabase-js": "^2.57.2"
|
|
29
29
|
},
|
|
30
30
|
"scripts": {
|
|
31
31
|
"test-ci": "jest --runInBand",
|