Skip to content

Commit dc6dc38

Browse files
MagnusHJensenMagnusHJensen
andauthored
Feature/support version 0.28.2 of the storage api (#26)
* add javadoc to main interfaces/classes * bump compiled code to java 17 * add transform options add more tests add info to changelog bump version * update GHA secret name * update GHA secret name * update pom.xml reference * usa java 17 on GHA * Update tests Co-authored-by: MagnusHJensen <magnus.holm.jensen@lego.dk>
1 parent a64c709 commit dc6dc38

23 files changed

+665
-158
lines changed

.github/workflows/main.yml

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -14,15 +14,15 @@ jobs:
1414
- name: Clone Repository
1515
uses: actions/checkout@v3
1616

17-
- name: Setup JDK 8
17+
- name: Setup JDK 17
1818
uses: actions/setup-java@v3
1919
with:
20-
java-version: '8'
20+
java-version: '17'
2121
distribution: 'adopt'
2222
cache: maven
2323
server-id: 'github'
2424
server-username: 'supabase-community'
25-
server-password: ${{ secrets.GITHUB_TOKEN }}
25+
server-password: ${{ secrets.PACKAGES_PAT }}
2626

2727
- name: Run docker compose
2828
run: cd infra && docker compose up -d
@@ -38,5 +38,5 @@ jobs:
3838
with:
3939
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
4040
javadoc-branch: javadoc
41-
java-version: 8
41+
java-version: 17
4242
project: maven

.github/workflows/pull_request.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,10 +17,10 @@ jobs:
1717
steps:
1818
- name: Clone Repository
1919
uses: actions/checkout@v3
20-
- name: Setup JDK 8
20+
- name: Setup JDK 17
2121
uses: actions/setup-java@v3
2222
with:
23-
java-version: '8'
23+
java-version: '17'
2424
distribution: 'adopt'
2525
cache: maven
2626
- name: Run docker compose

CHANGELOG.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1 +1,6 @@
11
# Changelog
2+
3+
## v1.0.0 - [Supports v0.28.2](https://github.com/supabase/storage-api/releases/tag/v0.28.2)
4+
- Added new `FileTransformOptions`.
5+
- Updated [javadocs](https://supabase-community.github.io/storage-java)
6+
- Cleaned up code a bit.

README.md

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,13 +5,15 @@
55
# storage-java
66
An async Java client library for the [Supabase Storage API](https://github.com/supabase/storage-api)
77

8+
The version being used supports different version of the storage API, you can find which version supports up to what version in the [CHANGELOG](./CHANGELOG.md)
9+
810
## Example
11+
912
```java
1013
import io.supabase.StorageClient;
1114
import io.supabase.api.IStorageFileAPI;
1215
import io.supabase.data.bucket.CreateBucketResponse;
13-
import io.supabase.data.file.FileDownloadOption;
14-
import io.supabase.data.file.FilePathResponse;
16+
import io.supabase.data.file.*;
1517

1618
import java.io.File;
1719
import java.util.concurrent.CompletableFuture;
@@ -36,13 +38,13 @@ public class Main {
3638
FilePathResponse response = fileAPI.upload("my-secret-image/image.png", new File("file-path-to-image.png")).get();
3739

3840
// Generate a public url (The link is only valid if the bucket is public).
39-
fileAPI.getPublicUrl("my-secret-image/image.png", new FileDownloadOption(false));
41+
fileAPI.getPublicUrl("my-secret-image/image.png", new FileDownloadOption(false), new FileTransformOptions(500, 500, ResizeOption.COVER, 50, FormatOption.NONE));
4042

4143
// Create a signed url to download an object in a private bucket that expires in 60 seconds, and will be downloaded instantly on link as "my-image.png"
42-
fileAPI.getSignedUrl("my-secret-image/image.png", 60, new FileDownloadOption("my-image.png"));
44+
fileAPI.getSignedUrl("my-secret-image/image.png", 60, new FileDownloadOption("my-image.png"), null);
4345

4446
// Download the file
45-
fileAPI.download("my-secret-image/image.png");
47+
fileAPI.download("my-secret-image/image.png", null);
4648

4749
} catch (InterruptedException | ExecutionException e) {
4850
throw new RuntimeException(e);

infra/docker-compose.yml

Lines changed: 31 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -17,20 +17,22 @@ services:
1717
ports:
1818
- '3000:3000'
1919
depends_on:
20-
- db
20+
storage:
21+
condition: service_healthy
2122
restart: always
2223
environment:
2324
PGRST_DB_URI: postgres://postgres:postgres@db:5432/postgres
2425
PGRST_DB_SCHEMA: public, storage
2526
PGRST_DB_ANON_ROLE: postgres
2627
PGRST_JWT_SECRET: super-secret-jwt-token-with-at-least-32-characters-long
2728
storage:
28-
image: supabase/storage-api:v0.20.2
29+
build:
30+
context: ./storage
2931
ports:
3032
- '5000:5000'
3133
depends_on:
32-
- db
33-
- rest
34+
db:
35+
condition: service_healthy
3436
restart: always
3537
environment:
3638
ANON_KEY: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJyb2xlIjoiYW5vbiIsImlhdCI6MTYxMzUzMTk4NSwiZXhwIjoxOTI5MTA3OTg1fQ.ReNhHIoXIOa-8tL1DO3e26mJmOTnYuvdgobwIYGzrLQ
@@ -47,6 +49,12 @@ services:
4749
FILE_SIZE_LIMIT: 52428800
4850
STORAGE_BACKEND: file
4951
FILE_STORAGE_BACKEND_PATH: /tmp/storage
52+
ENABLE_IMAGE_TRANSFORMATION: "true"
53+
IMGPROXY_URL: http://imgproxy:8080
54+
volumes:
55+
- assets-volume:/tmp/storage
56+
healthcheck:
57+
test: [ 'CMD-SHELL', 'curl -f -LI http://localhost:5000/status' ]
5058

5159
db:
5260
build:
@@ -61,4 +69,22 @@ services:
6169
POSTGRES_DB: postgres
6270
POSTGRES_USER: postgres
6371
POSTGRES_PASSWORD: postgres
64-
POSTGRES_PORT: 5432
72+
POSTGRES_PORT: 5432
73+
healthcheck:
74+
test: [ "CMD-SHELL", "pg_isready" ]
75+
interval: 10s
76+
timeout: 5s
77+
retries: 5
78+
79+
imgproxy:
80+
image: darthsim/imgproxy
81+
ports:
82+
- "50020:8080"
83+
volumes:
84+
- assets-volume:/tmp/storage
85+
environment:
86+
- IMGPROXY_LOCAL_FILESYSTEM_ROOT=/
87+
- IMGPROXY_USE_ETAG=true
88+
- IMGPROXY_ENABLE_WEBP_DETECTION=true
89+
volumes:
90+
assets-volume:

infra/storage/Dockerfile

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
FROM supabase/storage-api:v0.28.0
2+
3+
RUN apk add curl --no-cache

pom.xml

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66

77
<groupId>io.supabase</groupId>
88
<artifactId>storage-java</artifactId>
9-
<version>0.1.0</version>
9+
<version>1.0.0</version>
1010

1111
<name>Storage Java</name>
1212
<description>An async client library for the Supabase Storage API in Java</description>
@@ -83,11 +83,6 @@
8383
<artifactId>maven-surefire-plugin</artifactId>
8484
<version>2.22.2</version>
8585
<dependencies>
86-
<dependency>
87-
<groupId>org.junit.platform</groupId>
88-
<artifactId>junit-platform-surefire-provider</artifactId>
89-
<version>1.3.2</version>
90-
</dependency>
9186
<dependency>
9287
<groupId>org.junit.jupiter</groupId>
9388
<artifactId>junit-jupiter-engine</artifactId>
@@ -121,12 +116,20 @@
121116
</execution>
122117
</executions>
123118
</plugin>
119+
<plugin>
120+
<groupId>org.apache.maven.plugins</groupId>
121+
<artifactId>maven-compiler-plugin</artifactId>
122+
<configuration>
123+
<source>${maven.compiler.source}</source>
124+
<target>${maven.compiler.target}</target>
125+
</configuration>
126+
</plugin>
124127
</plugins>
125128
</build>
126129

127130
<properties>
128-
<maven.compiler.source>8</maven.compiler.source>
129-
<maven.compiler.target>8</maven.compiler.target>
131+
<maven.compiler.source>17</maven.compiler.source>
132+
<maven.compiler.target>17</maven.compiler.target>
130133
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
131134
</properties>
132135

src/main/java/io/supabase/StorageClient.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ public class StorageClient extends StorageBucketAPI implements IStorageClient {
1212
private final Map<String, String> headers;
1313

1414
public StorageClient(String apiKey, String url) {
15-
this(url, new HashMap<String, String>() {{
15+
this(url, new HashMap<>() {{
1616
put("Authorization", "Bearer " + apiKey);
1717
}});
1818
// Validate URL and throw if not a valid url.

src/main/java/io/supabase/api/IStorageBucketAPI.java

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,21 +11,62 @@
1111

1212
public interface IStorageBucketAPI {
1313

14+
/**
15+
* <p>POST /bucket/</p>
16+
*
17+
* @param bucketId The name/id of the bucket you want to create.
18+
* @return a {@link CreateBucketResponse} object.
19+
*/
1420
CompletableFuture<CreateBucketResponse> createBucket(String bucketId);
21+
22+
/**
23+
* <p>POST /bucket/</p>
24+
*
25+
* @param bucketId The name/id of the bucket you want to create.
26+
* @param options The options you want to pass for the bucket creation.
27+
* @return a {@link CreateBucketResponse} object.
28+
*/
1529
CompletableFuture<CreateBucketResponse> createBucket(String bucketId, BucketCreateOptions options);
1630

1731
/**
32+
* <p>GET /bucket/</p>
1833
* Lists all buckets in the project.
34+
*
1935
* @return A list of all buckets.
2036
*/
2137
CompletableFuture<List<Bucket>> listBuckets();
2238

39+
/**
40+
* <p>POST /bucket/{bucketId}/empty</p>
41+
*
42+
* @param bucketId The bucket you want to empty.
43+
* @return a status message
44+
*/
2345
CompletableFuture<MessageResponse> emptyBucket(String bucketId);
2446

47+
/**
48+
* <p>GET /bucket/{bucketId}/</p>
49+
*
50+
* @param bucketId The bucket of which you want to retrieve.
51+
* @return the asked for bucket
52+
*/
2553
CompletableFuture<Bucket> getBucket(String bucketId);
2654

55+
/**
56+
* <p>PUT /bucket/{bucketId}/</p>
57+
*
58+
* @param bucketId The bucket you want to update
59+
* @param options The options to update the bucket to.
60+
* @return a status message
61+
*/
2762
CompletableFuture<MessageResponse> updateBucket(String bucketId, BucketUpdateOptions options);
2863

64+
/**
65+
* <p>DELETE /bucket/{bucketId}</p>
66+
*
67+
* @param bucketId The bucket of which you want to delete.
68+
* @return a status message
69+
*/
2970
CompletableFuture<MessageResponse> deleteBucket(String bucketId);
3071

3172
}

src/main/java/io/supabase/api/IStorageFileAPI.java

Lines changed: 95 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,16 +9,107 @@
99

1010
public interface IStorageFileAPI {
1111

12+
/**
13+
* <p>POST /object/{bucketName}/{wildcard}</p>
14+
*
15+
* @param path The path to the file within the bucket of where it should be uploaded.
16+
* @param file The file that needs to be uploaded.
17+
* @return a {@link FilePathResponse}
18+
*/
1219
CompletableFuture<FilePathResponse> upload(String path, File file);
20+
21+
/**
22+
* <p>PUT /object/{bucketName}/{wildcard}</p>
23+
*
24+
* @param path The path to the file within the bucket that should get updated.
25+
* @param file The new file that should be placed.
26+
* @return a {@link FilePathResponse}
27+
*/
1328
CompletableFuture<FilePathResponse> update(String path, File file);
29+
30+
/**
31+
* <p>POST /object/move/</p>
32+
*
33+
* @param fromPath The path to the object that needs to be moved.
34+
* @param toPath The new path where the object should be moved to.
35+
* @return a {@link MessageResponse}
36+
*/
1437
CompletableFuture<MessageResponse> move(String fromPath, String toPath);
38+
39+
/**
40+
* <p>POST /object/copy/</p>
41+
*
42+
* @param fromPath The path to the object that needs to be copied.
43+
* @param toPath The new path where the object should be copied to.
44+
* @return a {@link FilePathResponse}
45+
*/
1546
CompletableFuture<FilePathResponse> copy(String fromPath, String toPath);
16-
CompletableFuture<FileSignedUrlResponse> getSignedUrl(String path, int expiresIn, FileDownloadOption options);
17-
CompletableFuture<List<FileSignedUrlResponse>> getSignedUrls(List<String> paths, int expiresIn, FileDownloadOption options);
18-
CompletableFuture<FileDownload> download(String path);
19-
FilePublicUrlResponse getPublicUrl(String path, FileDownloadOption options);
2047

48+
/**
49+
* <p>POST /object/sign/{bucketName}</p>
50+
* <p>This method just wraps {@link #getSignedUrls(List, int, FileDownloadOption, FileTransformOptions)}</p>
51+
*
52+
* @param path The singular file path that should be signed.
53+
* @param expiresIn how many seconds until the signed url expires.
54+
* @param downloadOptions any additional download options.
55+
* @param transformOptions The transform options if any
56+
* @return a {@link FileSignedUrlResponse}
57+
*/
58+
CompletableFuture<FileSignedUrlResponse> getSignedUrl(String path, int expiresIn, FileDownloadOption downloadOptions, FileTransformOptions transformOptions);
59+
60+
/**
61+
* <p>POST /object/sign/{bucketName}</p>
62+
*
63+
* @param paths a list of file paths that should be signed.
64+
* @param expiresIn how many seconds until the signed urls expires.
65+
* @param downloadOptions any additional download options.
66+
* @param transformOptions The transform options if any
67+
* @return a list of {@link FileSignedUrlResponse}
68+
*/
69+
CompletableFuture<List<FileSignedUrlResponse>> getSignedUrls(List<String> paths, int expiresIn, FileDownloadOption downloadOptions, FileTransformOptions transformOptions);
70+
71+
/**
72+
* <p>Downloads a file from a private bucket. To download something from a public bucket, make a request to the url from {@link #getPublicUrl(String, FileDownloadOption, FileTransformOptions)}</p>
73+
* <p>GET /object/authenticated/{bucketName}/{wildcard}</p>
74+
*
75+
* @param path The path of the file to download
76+
* @param transformOptions The transform options if any
77+
* @return a {@link FileDownload}
78+
*/
79+
CompletableFuture<FileDownload> download(String path, FileTransformOptions transformOptions);
80+
81+
/**
82+
* Creates the url for an object in a public bucket
83+
*
84+
* @param path The path of the file the link should point to.
85+
* @param downloadOptions The download options if any.
86+
* @param transformOptions The transform options if any
87+
* @return a {@link FilePublicUrlResponse}
88+
*/
89+
FilePublicUrlResponse getPublicUrl(String path, FileDownloadOption downloadOptions, FileTransformOptions transformOptions);
90+
91+
/**
92+
* <p>POST /object/list/{bucketName}</p>
93+
*
94+
* @param options Options for the file search
95+
* @return a list of {@link io.supabase.data.file.File}
96+
*/
2197
CompletableFuture<List<io.supabase.data.file.File>> list(FileSearchOptions options);
98+
99+
/**
100+
* <p>POST /object/list/{bucketName}</p>
101+
*
102+
* @param path The prefix to list objects by
103+
* @param options Options for the file search
104+
* @return a list of {@link io.supabase.data.file.File}
105+
*/
22106
CompletableFuture<List<io.supabase.data.file.File>> list(String path, FileSearchOptions options);
107+
108+
/**
109+
* <p>DELETE /object/{bucketName}</p>
110+
*
111+
* @param paths a list of paths to files that should be deleted. BE WARY! PROVIDING NULL OR AN EMPTY LIST WILL DELETE THE ENTIRE BUCKET!
112+
* @return a list of the deleted files
113+
*/
23114
CompletableFuture<List<io.supabase.data.file.File>> delete(List<String> paths);
24115
}

0 commit comments

Comments
 (0)