@quatrain/storage-supabase 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/lib/SupabaseStorageAdapter.d.ts +22 -0
- package/lib/SupabaseStorageAdapter.js +142 -0
- package/lib/index.d.ts +2 -0
- package/lib/index.js +5 -0
- package/package.json +35 -0
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
/// <reference types="node" />
|
|
2
|
+
/// <reference types="node" />
|
|
3
|
+
import { AbstractStorageAdapter, FileType, FileResponseLinkType, StorageParameters, DownloadFileMetaType } from '@quatrain/storage';
|
|
4
|
+
import { Readable, Stream } from 'stream';
|
|
5
|
+
import { SupabaseClient } from '@supabase/supabase-js';
|
|
6
|
+
export declare class SupabaseStorageAdapter extends AbstractStorageAdapter {
|
|
7
|
+
protected _client: SupabaseClient;
|
|
8
|
+
constructor(params: StorageParameters);
|
|
9
|
+
getDriver(): SupabaseClient<any, "public", any>;
|
|
10
|
+
streamToBuffer(stream: Stream): Promise<Buffer>;
|
|
11
|
+
create(file: FileType, stream: Readable): Promise<FileType>;
|
|
12
|
+
copy(file: FileType, destFile: FileType): Promise<void>;
|
|
13
|
+
getUrl(file: FileType, expiresIn?: number): Promise<{
|
|
14
|
+
url: string;
|
|
15
|
+
expiresIn: number;
|
|
16
|
+
}>;
|
|
17
|
+
delete(file: FileType): Promise<boolean>;
|
|
18
|
+
getReadable(file: FileType): Promise<Readable>;
|
|
19
|
+
stream(file: FileType, res: any): Promise<any>;
|
|
20
|
+
download(file: FileType, meta: DownloadFileMetaType): Promise<string | Blob>;
|
|
21
|
+
getUploadUrl(file: FileType, _expiresIn?: number): Promise<FileResponseLinkType>;
|
|
22
|
+
}
|
|
@@ -0,0 +1,142 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
3
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
4
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
5
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
6
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
7
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
8
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
9
|
+
});
|
|
10
|
+
};
|
|
11
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
+
exports.SupabaseStorageAdapter = void 0;
|
|
13
|
+
const storage_1 = require("@quatrain/storage");
|
|
14
|
+
const stream_1 = require("stream");
|
|
15
|
+
const supabase_js_1 = require("@supabase/supabase-js");
|
|
16
|
+
const os_1 = require("os");
|
|
17
|
+
const path_1 = require("path");
|
|
18
|
+
class SupabaseStorageAdapter extends storage_1.AbstractStorageAdapter {
|
|
19
|
+
constructor(params) {
|
|
20
|
+
super(params);
|
|
21
|
+
this._client = (0, supabase_js_1.createClient)(this._params.config.url, this._params.config.secret);
|
|
22
|
+
storage_1.Storage.log(`[ASA] Supabase Storage Adapter initialized`);
|
|
23
|
+
}
|
|
24
|
+
getDriver() {
|
|
25
|
+
return this._client;
|
|
26
|
+
}
|
|
27
|
+
streamToBuffer(stream) {
|
|
28
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
29
|
+
return new Promise((resolve, reject) => {
|
|
30
|
+
const _buf = [];
|
|
31
|
+
stream.on('data', (chunk) => _buf.push(chunk));
|
|
32
|
+
stream.on('end', () => resolve(Buffer.concat(_buf)));
|
|
33
|
+
stream.on('error', (err) => reject(err));
|
|
34
|
+
});
|
|
35
|
+
});
|
|
36
|
+
}
|
|
37
|
+
create(file, stream) {
|
|
38
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
39
|
+
storage_1.Storage.log(`Uploading ${file.ref} to ${file.bucket}`);
|
|
40
|
+
const { data, error } = yield this._client.storage
|
|
41
|
+
.from(file.bucket)
|
|
42
|
+
.upload(file.ref, yield this.streamToBuffer(stream), {
|
|
43
|
+
cacheControl: '3600',
|
|
44
|
+
upsert: false,
|
|
45
|
+
});
|
|
46
|
+
return file;
|
|
47
|
+
});
|
|
48
|
+
}
|
|
49
|
+
copy(file, destFile) {
|
|
50
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
51
|
+
try {
|
|
52
|
+
const response = yield this._client.storage
|
|
53
|
+
.from(file.bucket)
|
|
54
|
+
.copy(file.ref, destFile.ref, {
|
|
55
|
+
destinationBucket: destFile.bucket,
|
|
56
|
+
});
|
|
57
|
+
console.log(response);
|
|
58
|
+
}
|
|
59
|
+
catch (err) {
|
|
60
|
+
console.error(err);
|
|
61
|
+
}
|
|
62
|
+
});
|
|
63
|
+
}
|
|
64
|
+
getUrl(file, expiresIn = 3600) {
|
|
65
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
66
|
+
const { data, error } = yield this._client.storage
|
|
67
|
+
.from(file.bucket)
|
|
68
|
+
.createSignedUrl(file.path, expiresIn);
|
|
69
|
+
if (error !== null) {
|
|
70
|
+
throw new Error(`Unable to get signed url: ${error}`);
|
|
71
|
+
}
|
|
72
|
+
return { url: data === null || data === void 0 ? void 0 : data.signedUrl, expiresIn };
|
|
73
|
+
});
|
|
74
|
+
}
|
|
75
|
+
delete(file) {
|
|
76
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
77
|
+
const { error } = yield this._client.storage
|
|
78
|
+
.from(file.bucket)
|
|
79
|
+
.remove([file.ref]);
|
|
80
|
+
if (error !== null) {
|
|
81
|
+
throw new Error(`Unable to delete ${file.ref}`);
|
|
82
|
+
}
|
|
83
|
+
storage_1.Storage.log('Success. Object deleted.');
|
|
84
|
+
return true;
|
|
85
|
+
});
|
|
86
|
+
}
|
|
87
|
+
getReadable(file) {
|
|
88
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
89
|
+
storage_1.Storage.log(`GET Readable : ${file.ref}`);
|
|
90
|
+
const path = (0, path_1.join)((0, os_1.tmpdir)(), String(Date.now()));
|
|
91
|
+
const item = yield this.download(file, { path, onlyContent: true });
|
|
92
|
+
const buffer = Buffer.from(item.toString(), 'base64');
|
|
93
|
+
const readable = new stream_1.Readable();
|
|
94
|
+
readable.push(buffer);
|
|
95
|
+
readable.push(null);
|
|
96
|
+
return readable;
|
|
97
|
+
});
|
|
98
|
+
}
|
|
99
|
+
stream(file, res) {
|
|
100
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
101
|
+
storage_1.Storage.log(`GET Stream : ${file.ref}`);
|
|
102
|
+
const path = (0, path_1.join)((0, os_1.tmpdir)(), String(Date.now()));
|
|
103
|
+
const item = yield this.download(file, { path, onlyContent: true });
|
|
104
|
+
const buffer = Buffer.from(item.toString(), 'base64');
|
|
105
|
+
const readable = new stream_1.Readable();
|
|
106
|
+
readable.push(buffer);
|
|
107
|
+
readable.push(null);
|
|
108
|
+
return readable.pipe(res);
|
|
109
|
+
});
|
|
110
|
+
}
|
|
111
|
+
download(file, meta) {
|
|
112
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
113
|
+
const { data, error } = yield this._client.storage
|
|
114
|
+
.from(file.bucket)
|
|
115
|
+
.download(meta.path);
|
|
116
|
+
if (error !== null) {
|
|
117
|
+
throw new Error(`Unable to download ${file.ref}`);
|
|
118
|
+
}
|
|
119
|
+
if (meta.onlyContent) {
|
|
120
|
+
return data;
|
|
121
|
+
}
|
|
122
|
+
return meta.path;
|
|
123
|
+
});
|
|
124
|
+
}
|
|
125
|
+
getUploadUrl(file, _expiresIn = 3600) {
|
|
126
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
127
|
+
const { data, error } = yield this._client.storage
|
|
128
|
+
.from(file.bucket)
|
|
129
|
+
.createSignedUploadUrl(file.ref);
|
|
130
|
+
if (error !== null) {
|
|
131
|
+
throw new Error(`Unable to get signed upload url: ${error}`);
|
|
132
|
+
}
|
|
133
|
+
return {
|
|
134
|
+
href: data === null || data === void 0 ? void 0 : data.signedUrl,
|
|
135
|
+
type: 'PUT',
|
|
136
|
+
accept: file.contentType || 'application/octet-stream',
|
|
137
|
+
expiresIn: 7200, // fixed value in Supabase
|
|
138
|
+
};
|
|
139
|
+
});
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
exports.SupabaseStorageAdapter = SupabaseStorageAdapter;
|
package/lib/index.d.ts
ADDED
package/lib/index.js
ADDED
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.SupabaseStorageAdapter = void 0;
|
|
4
|
+
const SupabaseStorageAdapter_1 = require("./SupabaseStorageAdapter");
|
|
5
|
+
Object.defineProperty(exports, "SupabaseStorageAdapter", { enumerable: true, get: function () { return SupabaseStorageAdapter_1.SupabaseStorageAdapter; } });
|
package/package.json
ADDED
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@quatrain/storage-supabase",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "Storage adapter for Supabase Storage",
|
|
5
|
+
"main": "lib/index.js",
|
|
6
|
+
"types": "lib/index.d.ts",
|
|
7
|
+
"files": [
|
|
8
|
+
"lib/",
|
|
9
|
+
"README.md"
|
|
10
|
+
],
|
|
11
|
+
"author": "Quatrain Développement SAS <developers@quatrain.com>",
|
|
12
|
+
"license": "MIT",
|
|
13
|
+
"devDependencies": {
|
|
14
|
+
"@tsconfig/recommended": "^1.0.1",
|
|
15
|
+
"@types/jest": "^27.0.3",
|
|
16
|
+
"jest": "^27.4.7",
|
|
17
|
+
"jest-node-exports-resolver": "^1.1.6",
|
|
18
|
+
"trace-unhandled": "^2.0.1",
|
|
19
|
+
"ts-jest": "^27.1.2",
|
|
20
|
+
"ts-node": "^10.4.0",
|
|
21
|
+
"typescript": "^5.1.5"
|
|
22
|
+
},
|
|
23
|
+
"dependencies": {
|
|
24
|
+
"@quatrain/core": "^1.0.0-beta13",
|
|
25
|
+
"@quatrain/storage": "^0.1.0",
|
|
26
|
+
"@supabase/supabase-js": "^2.45.1"
|
|
27
|
+
},
|
|
28
|
+
"scripts": {
|
|
29
|
+
"test": "tsc && jest --verbose",
|
|
30
|
+
"build": "tsc --watch",
|
|
31
|
+
"patch": "yarn version --patch --no-git-tag-version",
|
|
32
|
+
"push": "yarn publish --access public",
|
|
33
|
+
"prepublish": "tsc"
|
|
34
|
+
}
|
|
35
|
+
}
|