@directus/storage-driver-supabase 1.0.10 → 1.0.12
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/index.d.ts +5 -5
- package/dist/index.js +43 -24
- package/license +1 -1
- package/package.json +7 -7
package/dist/index.d.ts
CHANGED
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import * as undici from 'undici';
|
|
2
1
|
import { Driver, Range } from '@directus/storage';
|
|
3
2
|
import { Readable } from 'node:stream';
|
|
4
3
|
|
|
@@ -6,6 +5,7 @@ type DriverSupabaseConfig = {
|
|
|
6
5
|
bucket: string;
|
|
7
6
|
serviceRole: string;
|
|
8
7
|
projectId?: string;
|
|
8
|
+
/** Allows a custom Supabase endpoint for self-hosting */
|
|
9
9
|
endpoint?: string;
|
|
10
10
|
root?: string;
|
|
11
11
|
};
|
|
@@ -17,12 +17,11 @@ declare class DriverSupabase implements Driver {
|
|
|
17
17
|
private get endpoint();
|
|
18
18
|
private getClient;
|
|
19
19
|
private getBucket;
|
|
20
|
-
private
|
|
20
|
+
private fullPath;
|
|
21
21
|
private getAuthenticatedUrl;
|
|
22
22
|
read(filepath: string, range?: Range): Promise<Readable>;
|
|
23
|
-
head(filepath: string): Promise<undici.Headers>;
|
|
24
23
|
stat(filepath: string): Promise<{
|
|
25
|
-
size:
|
|
24
|
+
size: any;
|
|
26
25
|
modified: Date;
|
|
27
26
|
}>;
|
|
28
27
|
exists(filepath: string): Promise<boolean>;
|
|
@@ -30,7 +29,8 @@ declare class DriverSupabase implements Driver {
|
|
|
30
29
|
copy(src: string, dest: string): Promise<void>;
|
|
31
30
|
write(filepath: string, content: Readable, type?: string): Promise<void>;
|
|
32
31
|
delete(filepath: string): Promise<void>;
|
|
33
|
-
list(prefix?: string):
|
|
32
|
+
list(prefix?: string): AsyncIterable<string>;
|
|
33
|
+
listGenerator(prefix: string): AsyncIterable<string>;
|
|
34
34
|
}
|
|
35
35
|
|
|
36
36
|
export { DriverSupabase, type DriverSupabaseConfig, DriverSupabase as default };
|
package/dist/index.js
CHANGED
|
@@ -9,7 +9,10 @@ var DriverSupabase = class {
|
|
|
9
9
|
client;
|
|
10
10
|
bucket;
|
|
11
11
|
constructor(config) {
|
|
12
|
-
this.config =
|
|
12
|
+
this.config = {
|
|
13
|
+
...config,
|
|
14
|
+
root: normalizePath(config.root ?? "", { removeLeading: true })
|
|
15
|
+
};
|
|
13
16
|
this.client = this.getClient();
|
|
14
17
|
this.bucket = this.getBucket();
|
|
15
18
|
}
|
|
@@ -34,11 +37,14 @@ var DriverSupabase = class {
|
|
|
34
37
|
}
|
|
35
38
|
return this.client.from(this.config.bucket);
|
|
36
39
|
}
|
|
37
|
-
|
|
38
|
-
|
|
40
|
+
fullPath(filepath) {
|
|
41
|
+
const path = join(this.config.root, filepath);
|
|
42
|
+
if (path === ".")
|
|
43
|
+
return "";
|
|
44
|
+
return normalizePath(path);
|
|
39
45
|
}
|
|
40
46
|
getAuthenticatedUrl(filepath) {
|
|
41
|
-
return `${this.endpoint}/${join("object/authenticated", this.config.bucket, this.
|
|
47
|
+
return `${this.endpoint}/${join("object/authenticated", this.config.bucket, this.fullPath(filepath))}`;
|
|
42
48
|
}
|
|
43
49
|
async read(filepath, range) {
|
|
44
50
|
const requestInit = { method: "GET" };
|
|
@@ -54,23 +60,17 @@ var DriverSupabase = class {
|
|
|
54
60
|
}
|
|
55
61
|
return Readable.fromWeb(response.body);
|
|
56
62
|
}
|
|
57
|
-
async
|
|
58
|
-
const
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
Authorization: `Bearer ${this.config.serviceRole}`
|
|
62
|
-
}
|
|
63
|
+
async stat(filepath) {
|
|
64
|
+
const { data, error } = await this.bucket.list(this.config.root, {
|
|
65
|
+
search: filepath,
|
|
66
|
+
limit: 1
|
|
63
67
|
});
|
|
64
|
-
if (
|
|
68
|
+
if (error || data.length === 0) {
|
|
65
69
|
throw new Error("File not found");
|
|
66
70
|
}
|
|
67
|
-
return response.headers;
|
|
68
|
-
}
|
|
69
|
-
async stat(filepath) {
|
|
70
|
-
const headers = await this.head(filepath);
|
|
71
71
|
return {
|
|
72
|
-
size:
|
|
73
|
-
modified: new Date(
|
|
72
|
+
size: data[0]?.metadata["contentLength"] ?? 0,
|
|
73
|
+
modified: new Date(data[0]?.metadata["lastModified"] || null)
|
|
74
74
|
};
|
|
75
75
|
}
|
|
76
76
|
async exists(filepath) {
|
|
@@ -82,13 +82,13 @@ var DriverSupabase = class {
|
|
|
82
82
|
}
|
|
83
83
|
}
|
|
84
84
|
async move(src, dest) {
|
|
85
|
-
await this.bucket.move(this.
|
|
85
|
+
await this.bucket.move(this.fullPath(src), this.fullPath(dest));
|
|
86
86
|
}
|
|
87
87
|
async copy(src, dest) {
|
|
88
|
-
await this.bucket.copy(this.
|
|
88
|
+
await this.bucket.copy(this.fullPath(src), this.fullPath(dest));
|
|
89
89
|
}
|
|
90
90
|
async write(filepath, content, type) {
|
|
91
|
-
await this.bucket.upload(this.
|
|
91
|
+
await this.bucket.upload(this.fullPath(filepath), content, {
|
|
92
92
|
contentType: type ?? "",
|
|
93
93
|
cacheControl: "3600",
|
|
94
94
|
upsert: true,
|
|
@@ -96,26 +96,45 @@ var DriverSupabase = class {
|
|
|
96
96
|
});
|
|
97
97
|
}
|
|
98
98
|
async delete(filepath) {
|
|
99
|
-
await this.bucket.remove([this.
|
|
99
|
+
await this.bucket.remove([this.fullPath(filepath)]);
|
|
100
|
+
}
|
|
101
|
+
list(prefix = "") {
|
|
102
|
+
const fullPrefix = this.fullPath(prefix);
|
|
103
|
+
return this.listGenerator(fullPrefix);
|
|
100
104
|
}
|
|
101
|
-
async *
|
|
105
|
+
async *listGenerator(prefix) {
|
|
102
106
|
const limit = 1e3;
|
|
103
107
|
let offset = 0;
|
|
104
108
|
let itemCount = 0;
|
|
109
|
+
const isDirectory = prefix.endsWith("/");
|
|
110
|
+
const prefixDirectory = isDirectory ? prefix : dirname(prefix);
|
|
111
|
+
const search = isDirectory ? "" : prefix.split("/").pop() ?? "";
|
|
105
112
|
do {
|
|
106
|
-
const { data, error } = await this.bucket.list(
|
|
113
|
+
const { data, error } = await this.bucket.list(prefixDirectory, {
|
|
114
|
+
limit,
|
|
115
|
+
offset,
|
|
116
|
+
search
|
|
117
|
+
});
|
|
107
118
|
if (!data || error) {
|
|
108
119
|
break;
|
|
109
120
|
}
|
|
110
121
|
itemCount = data.length;
|
|
111
122
|
offset += itemCount;
|
|
112
123
|
for (const item of data) {
|
|
113
|
-
|
|
124
|
+
const filePath = normalizePath(join(prefixDirectory, item.name));
|
|
125
|
+
if (item.id !== null) {
|
|
126
|
+
yield filePath.substring(this.config.root ? this.config.root.length + 1 : 0);
|
|
127
|
+
} else {
|
|
128
|
+
yield* this.listGenerator(`${filePath}/`);
|
|
129
|
+
}
|
|
114
130
|
}
|
|
115
131
|
} while (itemCount === limit);
|
|
116
132
|
}
|
|
117
133
|
};
|
|
118
134
|
var src_default = DriverSupabase;
|
|
135
|
+
function dirname(path) {
|
|
136
|
+
return path.split("/").slice(0, -1).join("/");
|
|
137
|
+
}
|
|
119
138
|
export {
|
|
120
139
|
DriverSupabase,
|
|
121
140
|
src_default as default
|
package/license
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
Licensor: Monospace, Inc.
|
|
2
2
|
|
|
3
3
|
Licensed Work: Directus
|
|
4
|
-
The Licensed Work is Copyright ©
|
|
4
|
+
The Licensed Work is Copyright © 2024 Monospace, Inc.
|
|
5
5
|
|
|
6
6
|
Additional Use Grant: You may use the Licensed Work in production as long as
|
|
7
7
|
your Total Finances do not exceed US $5,000,000 for the
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@directus/storage-driver-supabase",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.12",
|
|
4
4
|
"description": "Supabase file storage abstraction for `@directus/storage`",
|
|
5
5
|
"homepage": "https://directus.io",
|
|
6
6
|
"repository": {
|
|
@@ -22,16 +22,16 @@
|
|
|
22
22
|
],
|
|
23
23
|
"dependencies": {
|
|
24
24
|
"@supabase/storage-js": "2.5.5",
|
|
25
|
-
"undici": "6.
|
|
26
|
-
"@directus/
|
|
27
|
-
"@directus/
|
|
25
|
+
"undici": "6.15.0",
|
|
26
|
+
"@directus/storage": "10.0.12",
|
|
27
|
+
"@directus/utils": "11.0.8"
|
|
28
28
|
},
|
|
29
29
|
"devDependencies": {
|
|
30
30
|
"@ngneat/falso": "7.2.0",
|
|
31
|
-
"@vitest/coverage-v8": "1.3
|
|
31
|
+
"@vitest/coverage-v8": "1.5.3",
|
|
32
32
|
"tsup": "8.0.2",
|
|
33
|
-
"typescript": "5.
|
|
34
|
-
"vitest": "1.3
|
|
33
|
+
"typescript": "5.4.5",
|
|
34
|
+
"vitest": "1.5.3",
|
|
35
35
|
"@directus/tsconfig": "1.0.1"
|
|
36
36
|
},
|
|
37
37
|
"scripts": {
|