https://github.com/rclone-ui/rclone-sdk
https://github.com/rclone-ui/rclone-sdk
Last synced: 5 months ago
JSON representation
- Host: GitHub
- URL: https://github.com/rclone-ui/rclone-sdk
- Owner: rclone-ui
- License: mit
- Created: 2025-12-06T22:34:02.000Z (7 months ago)
- Default Branch: main
- Last Pushed: 2025-12-06T22:34:05.000Z (7 months ago)
- Last Synced: 2025-12-13T15:03:40.019Z (6 months ago)
- Language: Rust
- Size: 60.5 KB
- Stars: 1
- Watchers: 0
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
- awesome-rclone - rclone-sdk - Rust crate providing full client to rclone's RC REST API. Based on the [OpenAPI spec](https://github.com/rclone-ui/rclone-openapi). Used internally by Rclone UI.  (API Libraries and SDKs / Rust)
README
# Rclone SDK
**Full OpenAPI-based client for the Rclone RC API**
[](https://www.npmjs.com/package/rclone-sdk)
[](https://www.npmjs.com/package/rclone-sdk)
[](https://crates.io/crates/rclone-sdk)
[](https://crates.io/crates/rclone-sdk)
[](LICENSE)
Built on top of [**rclone-openapi**](https://github.com/rclone-ui/rclone-openapi) (by yours truly) ยท Works with **Vanilla Fetch** ยท **React Query** ยท **SWR** ยท **Rust**
## ๐ฆ Rust
```sh
cargo add rclone-sdk
```
```toml
[dependencies]
rclone-sdk = "1.72"
tokio = { version = "1", features = ["full"] }
```
```rust
use rclone_sdk::Client;
#[tokio::main]
async fn main() -> Result<(), Box> {
let client = Client::new("http://localhost:5572");
// Get rclone version info
let version = client.core_version(None, None).await?;
let v = version.into_inner();
println!("Rclone {} on {}/{}", v.version, v.os, v.arch);
// List all configured remotes
let remotes = client.config_listremotes(None, None).await?;
println!("Remotes: {:?}", remotes.into_inner().remotes);
// Get storage info for a remote
let about = client.operations_about(None, None, "gdrive:").await?;
let info = about.into_inner();
println!("Storage: {} / {} bytes used", info.used, info.total);
Ok(())
}
```
## ๐ฆ JavaScript / TypeScript
```sh
npm install rclone-sdk
```
### Vanilla
```ts
import createRCDClient from 'rclone-sdk'
const rcd = createRCDClient({ baseUrl: 'http://localhost:5572' })
// List all configured remotes
const { data: remotes } = await rcd.POST('/config/listremotes')
console.log(remotes?.remotes) // ['gdrive', 'dropbox', 's3']
// List files in a remote
const { data: files } = await rcd.POST('/operations/list', {
body: { fs: 'gdrive:', remote: 'Documents' }
})
console.log(files?.list)
// Get storage info for a remote
const { data: about } = await rcd.POST('/operations/about', {
body: { fs: 'gdrive:' }
})
console.log(`Used: ${about?.used} / ${about?.total}`)
```
### Tanstack/React Query
```tsx
import createRCDQueryClient from 'rclone-sdk/query'
const rq = createRCDQueryClient({ baseUrl: 'http://localhost:5572' })
function RemotesList() {
const { data, isLoading, error } = rq.useQuery('post', '/config/listremotes')
if (isLoading) return
Loading...
if (error) return Error: {error.message}
return (
- {remote}
{data?.remotes?.map(remote => (
))}
)
}
function StorageInfo({ remote }: { remote: string }) {
const { data } = rq.useQuery('post', '/operations/about', {
body: { fs: `${remote}:` }
})
return {data?.used} / {data?.total} bytes
}
```
### SWR
```tsx
import createRCDSWR from 'rclone-sdk/swr'
const swr = createRCDSWR({ baseUrl: 'http://localhost:5572' })
function RemotesList() {
const { data, error, isLoading } = swr.useQuery('post', '/config/listremotes')
if (isLoading) return
if (error) return
return (
- {remote}
{data?.remotes?.map(remote => (
))}
)
}
function FileList({ remote, path }: { remote: string; path: string }) {
const { data } = swr.useQuery('post', '/operations/list', {
body: { fs: `${remote}:`, remote: path }
})
return (
-
{item.IsDir ? '๐' : '๐'} {item.Name}
{data?.list?.map(item => (
))}
)
}
```
## Tips
Even though the client supports all HTTP methods, **`rclone`** expects everything as a _POST_ request.
If you want to wrap the client to only send POST requests and throw errors automatically, here's a quick snippet (adjust to taste):
```ts
import createRCDClient, {
type OpenApiMethodResponse,
type OpenApiClient,
type OpenApiClientPathsWithMethod,
type OpenApiMaybeOptionalInit,
type OpenApiRequiredKeysOf,
type RCDClient,
} from 'rclone-sdk'
type ClientPaths = T extends OpenApiClient ? P : never
type Paths = ClientPaths
type InitParam = OpenApiRequiredKeysOf extends never
? [(Init & { [key: string]: unknown })?]
: [Init & { [key: string]: unknown }]
export default async function rclone<
Path extends OpenApiClientPathsWithMethod,
Init extends OpenApiMaybeOptionalInit = OpenApiMaybeOptionalInit<
Paths[Path],
'post'
>,
>(
path: Path,
...init: InitParam
): Promise> {
const client = createRCDClient({ baseUrl: 'http://localhost:5572' })
const result = await client.POST(
path,
...(init as InitParam>)
)
if (result?.error) {
const message =
typeof result.error === 'string' ? result.error : JSON.stringify(result.error)
throw new Error(message)
}
const data = result.data as { error?: unknown } | undefined
if (data?.error) {
const message = typeof data.error === 'string' ? data.error : JSON.stringify(data.error)
throw new Error(message)
}
if (!result.response.ok) {
throw new Error(`${result.response.status} ${result.response.statusText}`)
}
return result.data as OpenApiMethodResponse
}
```
Now you'll be able to
- call **`rclone('config/listremotes')`** directly
- get the data as the return value (correctly typed, and without having to de-construct the resulting object)
- have it throw on error with a detailed error message (instead of checking the **`error`** field manually)
## Contributing
Contributions = welcome! Just make sure to check if the PR isn't a better fit for the [**rclone-openapi**](https://github.com/rclone-ui/rclone-ui) repo.
Made with โ๏ธ for the rclone community