Search by

krafsys / vercy-storage

krafsys

Laravel SDK for Vercy Cloud Storage: upload files and get public URLs with thumbnail and WebP variants.

Package info

github.com/krafsys/vercy-storage

pkg:composer/krafsys/vercy-storage

Statistics

Installs: 5

Dependents: 0

Suggesters: 0

Stars: 0

Open Issues: 0

v1.0.2 2026-11-02 12:54 UTC

This package is auto-updated.

Last update: 2026-11-02 12:55:57 UTC


README

Laravel SDK for Vercy Cloud Storage. Upload files and get back a public URL, plus helpers for the thumbnail (?size=sm) and WebP display (?size=md) image variants.

It wraps Vercy's documented upload API: a single PUT https://vercy.fun/api/v1/storage with the raw file as the body and metadata in headers (x-pathname, x-folder, x-access, Content-Type), authenticated with a Bearer API key.

Requires PHP 8.1+ and Laravel 10, 11, 12 or 13.

Scope

Only uploading is covered, because that is the only operation Vercy currently documents. Deleting, listing and presigned download links are not included. Private access (x-access: private) is marked "coming soon" by Vercy, so use public for now.

Installation

composer require krafsys/vercy-storage

The service provider and VercyStorage facade are auto-discovered. Set your key in .env (generate it in your Vercy Project Dashboard):

VERCY_STORAGE_API_KEY="vcy_storage_rw_proj_123_abc456..."

Optional overrides: VERCY_STORAGE_URL (upload endpoint) and VERCY_STORAGE_ACCESS (default public). To edit the full config:

php artisan vendor:publish --tag=vercy-storage-config

Usage

Upload

use Vercy\CloudStorage\Facades\VercyStorage;

$file = VercyStorage::put('avatars/profile.png', file_get_contents($path), [
    'access' => 'public',          // 'public' (default) or 'private' (coming soon)
    'contentType' => 'image/png',  // optional, detected when omitted
    'folder' => 'users',           // optional, one alphanumeric level (x-folder)
]);

$file->url;         // public URL
$file->thumbnail(); // {url}?size=sm
$file->display();   // {url}?size=md  (WebP)

$contents can be a string, a stream resource, a PSR-7 stream, an SplFileInfo, or a Laravel UploadedFile. Files and streams are sent as streams, not loaded into memory.

Upload from disk:

VercyStorage::putFile('documents/contract.pdf', storage_path('app/contract.pdf'));

In a controller

use Illuminate\Http\Request;
use Vercy\CloudStorage\Facades\VercyStorage;

public function upload(Request $request)
{
    $request->validate(['file' => ['required', 'image', 'max:5120']]);

    $upload = $request->file('file');

    $stored = VercyStorage::put('avatars/' . $upload->hashName(), $upload);

    $request->user()->update(['avatar_url' => $stored->url]);

    return response()->json([
        'url' => $stored->url,
        'thumbnail' => $stored->thumbnail(),
    ]);
}

You can also type-hint Vercy\CloudStorage\VercyStorage for dependency injection.

Variants from a saved URL

If you only stored the URL in your database:

use Vercy\CloudStorage\Data\StoredFile;

StoredFile::variantUrl($user->avatar_url, 'sm'); // thumbnail
StoredFile::variantUrl($user->avatar_url, 'md'); // WebP display

Error handling

Every failure throws Vercy\CloudStorage\Exceptions\VercyStorageException:

use Vercy\CloudStorage\Exceptions\VercyStorageException;

try {
    VercyStorage::put('a.txt', 'hello');
} catch (VercyStorageException $e) {
    $e->getMessage(); // human readable
    $e->status;       // HTTP status, or null (missing key, connection failure, bad input)
    $e->body;         // decoded error body, if any
}

Inputs are validated before any request is sent: pathname (non-empty, no control characters, since it travels as a header), x-folder (letters and digits only) and access level.

Retries

Off by default, because a retry re-sends the whole file. Set retries in the config to retry connection errors and 5xx responses; 4xx responses are never retried.

Testing your app

The client uses Laravel's HTTP client, so Http::fake() works:

Http::fake(['vercy.fun/api/v1/storage' => Http::response(['url' => 'https://vercy.fun/files/a.png'])]);

Run this package's own tests with composer install && composer test.

License

MIT