PG Cloud Storage
CloudBase JS SDK v3 PG mode provides PostgreSQL-native bucket-based cloud storage capabilities. Use app.storage.from(bucketId) to get the object client for a specific bucket. All path parameters are object names inside the bucket; do not pass cloud:// fileIDs.
Quick Start
import cloudbase from "@cloudbase/js-sdk";
const app = cloudbase.init({ env: "your-env-id" });
const bucket = app.storage.from("avatars");
const { data, error } = await bucket.upload("user-123/avatar.png", file, {
contentType: "image/png",
upsert: true,
});
if (error) throw error;
const { data: blob } = await bucket.download("user-123/avatar.png");
const { data: signed } = await bucket.createSignedUrl("user-123/avatar.png", 3600);
await bucket.remove(["user-123/avatar.png"]);
API Methods
Bucket Client
- from() - Select a bucket and return its object client
- throwOnError() - Throw on error
File Operations
- upload() - Upload files
- update() - Update files
- download() - Download files
- remove() - Delete files
- move() - Move files
- copy() - Copy files
- list() - List objects in a bucket
URL Management
- createSignedUrl() - Create a signed URL
- createSignedUrls() - Create signed URLs in batch
- getPublicUrl() - Get a public URL
- createSignedUploadUrl() - Create a signed upload URL
File Information
Bucket Management
- Bucket management - Create, query, update, and delete buckets
from
from(bucketId: string): PostgresNativeStorageFileApi
type PostgresNativeStorageFileApi = StorageFileApi;
Parameters
PG Bucket ID, corresponding to `storage.buckets.id`.
Response
Native PG bucket object operation client.
Example
const bucket = app.storage.from("avatars");
throwOnError
throwOnError(): this
Parameters
No parameters
Response
Current client instance for chaining.
Example
const bucket = app.storage.from("avatars").throwOnError();
await bucket.upload("user-123/avatar.png", file);
upload
Upload a file to storage.
upload(path: string, fileBody: FileBody, fileOptions?: UploadOptions): Promise<Result<UploadResult>>
type FileBody = File | Blob | ArrayBuffer | ArrayBufferView | FormData | ReadableStream<Uint8Array> | string;
type Result<T> = { data: T; error: null } | { data: null; error: StorageError };
interface UploadOptions {
cacheControl?: string;
contentType?: string;
metadata?: Record<string, any>;
upsert?: boolean; // default false
}
interface UploadResult {
id: string;
path: string;
fullPath: string; // bucketId/objectName
}
Parameters
Object name inside the bucket, for example `user-123/avatar.png`. Do not pass `cloud://` fileIDs.
File content.
Upload options. Pass `upsert: true` to overwrite existing objects.
Response
Return data
Error.
Example
const { data, error } = await app.storage.from("avatars").upload("user-123/avatar.png", file, {
contentType: "image/png",
upsert: true,
metadata: { usage: "avatar" },
});
if (error) throw error;
console.log(data.fullPath);
update
Update an existing file.
update(path: string, fileBody: FileBody, fileOptions?: UploadOptions): Promise<Result<UploadResult>>
interface UploadOptions {
cacheControl?: string;
contentType?: string;
metadata?: Record<string, any>;
}
Parameters
Object name inside the bucket.
New file content.
Upload options.
Response
Update result.
Error.
Example
await app.storage.from("avatars").update("user-123/avatar.png", newFile, {
contentType: "image/png",
});
download
Download a file.
download(path: string, options?: DownloadOptions, parameters?: FetchParameters): DownloadBuilder
interface DownloadOptions {
download?: string | boolean;
cacheNonce?: string;
}
interface FetchParameters {
signal?: AbortSignal;
cache?: RequestCache;
}
Parameters
Object name inside the bucket.
Download options.
Request control parameters.
Response
Await returns Blob by default. `.asStream()` returns ReadableStream.
Error.
Example
const { data: blob } = await app.storage.from("avatars").download("user-123/avatar.png");
const { data: stream } = await app.storage
.from("videos")
.download("demo.mp4")
.asStream();
remove
Delete one or more files.
remove(paths: string[]): Promise<Result<FullObject[]>>
interface FullObject {
name: string;
bucket_id: string;
owner_id?: string | null;
metadata?: Record<string, any>;
}
Parameters
Object names inside the bucket.
Response
Deleted object information.
Error.
Example
await app.storage.from("avatars").remove(["user-123/avatar.png"]);
move
Move a file to a new path.
move(fromPath: string, toPath: string, options?: DestinationOptions): Promise<Result<{ message: string }>>
interface DestinationOptions {
destinationBucket?: string;
upsert?: boolean;
}
Parameters
Source object name.
Destination object name.
Destination bucket options.
Response
Return data
Error.
Example
await app.storage.from("avatars").move("user-123/avatar.png", "user-123/archive/avatar.png");
copy
Copy a file to a new path.
copy(fromPath: string, toPath: string, options?: DestinationOptions): Promise<Result<{ path: string }>>
interface DestinationOptions {
destinationBucket?: string;
upsert?: boolean;
copyMetadata?: boolean;
metadata?: Record<string, any>;
}
Parameters
Source object name.
Destination object name.
Cross-bucket and metadata options.
Response
Return data
Error.
Example
await app.storage.from("avatars").copy("user-123/avatar.png", "user-123/avatar-copy.png", {
upsert: true,
copyMetadata: true,
});
createSignedUrl
Create a temporary access URL.
createSignedUrl(path: string, expiresIn: number, options?: SignedUrlOptions): Promise<Result<SignedUrlResult>>
interface SignedUrlOptions {
download?: string | boolean;
cacheNonce?: string;
}
interface SignedUrlResult {
fullSignedURL: string;
}
Parameters
Object name inside the bucket.
Expiration in seconds.
Signed URL options.
Response
Return data
Error.
Example
const { data } = await app.storage.from("avatars").createSignedUrl("user-123/avatar.png", 3600, {
download: "avatar.png",
});
createSignedUrls
Create temporary access URLs in batch.
createSignedUrls(paths: string[], expiresIn: number, options?: SignedUrlOptions): Promise<Result<SignedUrlsResultItem[]>>
interface SignedUrlsResultItem {
path: string;
fullSignedURL: string | null;
error: string | null;
}
Parameters
Object names inside the bucket.
Expiration in seconds.
Signed URL options.
Response
Batch signing results.
Error.
Example
await app.storage.from("avatars").createSignedUrls(["user-123/avatar.png"], 3600);
getPublicUrl
Get a public access URL.
getPublicUrl(path: string, options?: PublicUrlOptions): { data: { publicUrl: string } }
interface PublicUrlOptions {
download?: string | boolean;
cacheNonce?: string;
}
Parameters
Object name inside the bucket.
Public URL options.
Response
Return data
Example
const { data } = app.storage.from("public-assets").getPublicUrl("logos/cloudbase.png");
info
Get file information.
info(path: string): Promise<Result<ObjectInfo>>
interface ObjectInfo {
id: string;
name: string;
bucketId: string;
size?: number | null;
contentType?: string | null;
metadata?: Record<string, any>;
createdAt?: string | null;
}
Parameters
Object name inside the bucket.
Response
Object metadata.
Error.
Example
await app.storage.from("avatars").info("user-123/avatar.png");
exists
Check whether a file exists.
exists(path: string): Promise<Result<boolean>>
Parameters
Object name inside the bucket.
Response
Whether it exists.
Error.
Example
await app.storage.from("avatars").exists("user-123/avatar.png");
createSignedUploadUrl
Create a signed upload URL.
createSignedUploadUrl(path: string, options?: { upsert?: boolean }): Promise<Result<CreateSignedUploadUrlResult>>
interface CreateSignedUploadUrlResult {
fullSignedURL: string;
token: string;
path: string;
}
Parameters
Object name inside the bucket.
Whether to allow overwrite.
Response
Signed upload URL and token.
Error.
Example
const bucket = app.storage.from("avatars");
const { data: signed } = await bucket.createSignedUploadUrl("user-123/avatar.png", { upsert: true });
await bucket.uploadToSignedUrl("user-123/avatar.png", signed.token, file);
list
List objects in a bucket.
list(path?: string, options?: ListOptions, parameters?: FetchParameters): Promise<Result<ListObjectsResponse>>
interface ListOptions {
limit?: number;
cursor?: string;
withDelimiter?: boolean;
sortBy?: { column?: "name" | "created_at" | "updated_at"; order?: "asc" | "desc" };
}
Parameters
Prefix. Omit it to list the bucket root.
List options.
Response
Contains folders, objects, hasNext, and nextCursor.
Error.
Example
const { data } = await app.storage.from("avatars").list("user-123", {
limit: 20,
withDelimiter: true,
});
Bucket management
The following APIs are mounted directly on app.storage and are only available in PG mode:
listBuckets(options?: ListBucketOptions): Promise<Result<Bucket[]>>
getBucket(bucketId: string): Promise<Result<Bucket>>
createBucket(bucketId: string, options?: CreateBucketOptions): Promise<Result<{ name: string }>>
updateBucket(bucketId: string, options: UpdateBucketOptions): Promise<Result<{ message: string }>>
deleteBucket(bucketId: string): Promise<Result<{ message: string }>>
interface CreateBucketOptions {
public?: boolean;
type?: "STANDARD";
fileSizeLimit?: number | string | null;
allowedMimeTypes?: string[] | null;
}
Parameters
Bucket ID.
Bucket configuration.
Response
Bucket operation result.
Example
await app.storage.createBucket("avatars", {
public: false,
type: "STANDARD",
fileSizeLimit: "100MB",
allowedMimeTypes: ["image/png", "image/jpeg"],
});
const { data: buckets } = await app.storage.listBuckets({ limit: 20, offset: 0 });
Best Practices
1. Error handling
const { data, error } = await app.storage.from("avatars").upload("user-123/avatar.png", file);
if (error) {
console.error("Operation failed:", error.message);
return;
}
2. Path rules
- Select a bucket with
from(bucketId)first. All subsequent paths are object names inside that bucket. - Do not pass
cloud://fileIDs. - Do not start paths with
/or include consecutive/.
FAQ
1. Why should I not pass cloud:// fileIDs in PG mode?
The native PG API already selects the bucket through from(bucketId). Method path arguments are object names inside that bucket.
2. Where are file permissions configured?
PG mode is controlled by RLS policies on storage.objects / storage.buckets.