{"id":33919297,"url":"https://github.com/rclone-ui/rclone-sdk","last_synced_at":"2026-01-13T14:00:02.150Z","repository":{"id":328290846,"uuid":"1111419216","full_name":"rclone-ui/rclone-sdk","owner":"rclone-ui","description":null,"archived":false,"fork":false,"pushed_at":"2025-12-06T22:34:05.000Z","size":62,"stargazers_count":1,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2025-12-13T15:03:40.019Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Rust","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/rclone-ui.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2025-12-06T22:34:02.000Z","updated_at":"2025-12-07T23:15:23.000Z","dependencies_parsed_at":"2025-12-13T15:04:03.277Z","dependency_job_id":null,"html_url":"https://github.com/rclone-ui/rclone-sdk","commit_stats":null,"previous_names":["rclone-ui/rclone-sdk"],"tags_count":null,"template":false,"template_full_name":null,"purl":"pkg:github/rclone-ui/rclone-sdk","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rclone-ui%2Frclone-sdk","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rclone-ui%2Frclone-sdk/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rclone-ui%2Frclone-sdk/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rclone-ui%2Frclone-sdk/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/rclone-ui","download_url":"https://codeload.github.com/rclone-ui/rclone-sdk/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rclone-ui%2Frclone-sdk/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28387596,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-01-13T13:42:20.960Z","status":"ssl_error","status_checked_at":"2026-01-13T13:42:03.276Z","response_time":56,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2025-12-12T08:46:00.504Z","updated_at":"2026-01-13T14:00:02.137Z","avatar_url":"https://github.com/rclone-ui.png","language":"Rust","funding_links":[],"categories":["API Libraries and SDKs"],"sub_categories":["Rust"],"readme":"\u003cdiv align=\"center\"\u003e\n\n# Rclone SDK\n\n**Full OpenAPI-based client for the Rclone RC API**\n\n[![npm version](https://img.shields.io/npm/v/rclone-sdk?color=cb0000\u0026label=npm\u0026logo=npm)](https://www.npmjs.com/package/rclone-sdk)\n[![npm downloads](https://img.shields.io/npm/dm/rclone-sdk?color=cb0000\u0026logo=npm)](https://www.npmjs.com/package/rclone-sdk)\n[![crates.io](https://img.shields.io/crates/v/rclone-sdk?color=fc8d62\u0026logo=rust)](https://crates.io/crates/rclone-sdk)\n[![crates.io downloads](https://img.shields.io/crates/d/rclone-sdk?color=fc8d62\u0026logo=rust)](https://crates.io/crates/rclone-sdk)\n[![License: MIT](https://img.shields.io/badge/license-MIT-blue.svg)](LICENSE)\n\n\u003csub\u003eBuilt on top of [**rclone-openapi**](https://github.com/rclone-ui/rclone-openapi) (by yours truly) · Works with **Vanilla Fetch** · **React Query** · **SWR** · **Rust**\u003c/sub\u003e\n\n\u003c/div\u003e\n\n## 🦀 Rust\n\n```sh\ncargo add rclone-sdk\n```\n\n```toml\n[dependencies]\nrclone-sdk = \"1.72\"\ntokio = { version = \"1\", features = [\"full\"] }\n```\n\n```rust\nuse rclone_sdk::Client;\n\n#[tokio::main]\nasync fn main() -\u003e Result\u003c(), Box\u003cdyn std::error::Error\u003e\u003e {\n    let client = Client::new(\"http://localhost:5572\");\n\n    // Get rclone version info\n    let version = client.core_version(None, None).await?;\n    let v = version.into_inner();\n    println!(\"Rclone {} on {}/{}\", v.version, v.os, v.arch);\n\n    // List all configured remotes\n    let remotes = client.config_listremotes(None, None).await?;\n    println!(\"Remotes: {:?}\", remotes.into_inner().remotes);\n\n    // Get storage info for a remote\n    let about = client.operations_about(None, None, \"gdrive:\").await?;\n    let info = about.into_inner();\n    println!(\"Storage: {} / {} bytes used\", info.used, info.total);\n\n    Ok(())\n}\n```\n\n\n## 📦 JavaScript / TypeScript\n\n```sh\nnpm install rclone-sdk\n```\n\n### Vanilla\n\n```ts\nimport createRCDClient from 'rclone-sdk'\n\nconst rcd = createRCDClient({ baseUrl: 'http://localhost:5572' })\n\n// List all configured remotes\nconst { data: remotes } = await rcd.POST('/config/listremotes')\nconsole.log(remotes?.remotes) // ['gdrive', 'dropbox', 's3']\n\n// List files in a remote\nconst { data: files } = await rcd.POST('/operations/list', {\n    body: { fs: 'gdrive:', remote: 'Documents' }\n})\nconsole.log(files?.list)\n\n// Get storage info for a remote\nconst { data: about } = await rcd.POST('/operations/about', {\n    body: { fs: 'gdrive:' }\n})\nconsole.log(`Used: ${about?.used} / ${about?.total}`)\n```\n\n### Tanstack/React Query\n\n```tsx\nimport createRCDQueryClient from 'rclone-sdk/query'\n\nconst rq = createRCDQueryClient({ baseUrl: 'http://localhost:5572' })\n\nfunction RemotesList() {\n    const { data, isLoading, error } = rq.useQuery('post', '/config/listremotes')\n\n    if (isLoading) return \u003cdiv\u003eLoading...\u003c/div\u003e\n    if (error) return \u003cdiv\u003eError: {error.message}\u003c/div\u003e\n\n    return (\n        \u003cul\u003e\n            {data?.remotes?.map(remote =\u003e (\n                \u003cli key={remote}\u003e{remote}\u003c/li\u003e\n            ))}\n        \u003c/ul\u003e\n    )\n}\n\nfunction StorageInfo({ remote }: { remote: string }) {\n    const { data } = rq.useQuery('post', '/operations/about', {\n        body: { fs: `${remote}:` }\n    })\n\n    return \u003cspan\u003e{data?.used} / {data?.total} bytes\u003c/span\u003e\n}\n```\n\n### SWR\n\n```tsx\nimport createRCDSWR from 'rclone-sdk/swr'\n\nconst swr = createRCDSWR({ baseUrl: 'http://localhost:5572' })\n\nfunction RemotesList() {\n    const { data, error, isLoading } = swr.useQuery('post', '/config/listremotes')\n\n    if (isLoading) return \u003cdiv\u003eLoading...\u003c/div\u003e\n    if (error) return \u003cdiv\u003eError: {error.message}\u003c/div\u003e\n\n    return (\n        \u003cul\u003e\n            {data?.remotes?.map(remote =\u003e (\n                \u003cli key={remote}\u003e{remote}\u003c/li\u003e\n            ))}\n        \u003c/ul\u003e\n    )\n}\n\nfunction FileList({ remote, path }: { remote: string; path: string }) {\n    const { data } = swr.useQuery('post', '/operations/list', {\n        body: { fs: `${remote}:`, remote: path }\n    })\n\n    return (\n        \u003cul\u003e\n            {data?.list?.map(item =\u003e (\n                \u003cli key={item.Path}\u003e\n                    {item.IsDir ? '📁' : '📄'} {item.Name}\n                \u003c/li\u003e\n            ))}\n        \u003c/ul\u003e\n    )\n}\n```\n\n## Tips\n\nEven though the client supports all HTTP methods, **`rclone`** expects everything as a _POST_ request.\n\nIf you want to wrap the client to only send POST requests and throw errors automatically, here's a quick snippet (adjust to taste):\n```ts\nimport createRCDClient, {\n    type OpenApiMethodResponse,\n    type OpenApiClient,\n    type OpenApiClientPathsWithMethod,\n    type OpenApiMaybeOptionalInit,\n    type OpenApiRequiredKeysOf,\n    type RCDClient,\n} from 'rclone-sdk'\n\ntype ClientPaths\u003cT\u003e = T extends OpenApiClient\u003cinfer P, any\u003e ? P : never\ntype Paths = ClientPaths\u003cRCDClient\u003e\ntype InitParam\u003cInit\u003e = OpenApiRequiredKeysOf\u003cInit\u003e extends never\n    ? [(Init \u0026 { [key: string]: unknown })?]\n    : [Init \u0026 { [key: string]: unknown }]\n\nexport default async function rclone\u003c\n    Path extends OpenApiClientPathsWithMethod\u003cRCDClient, 'post'\u003e,\n    Init extends OpenApiMaybeOptionalInit\u003cPaths[Path], 'post'\u003e = OpenApiMaybeOptionalInit\u003c\n        Paths[Path],\n        'post'\n    \u003e,\n\u003e(\n    path: Path,\n    ...init: InitParam\u003cInit\u003e\n): Promise\u003cOpenApiMethodResponse\u003cRCDClient, 'post', Path, Init\u003e\u003e {\n    const client = createRCDClient({ baseUrl: 'http://localhost:5572' })\n\n    const result = await client.POST(\n        path,\n        ...(init as InitParam\u003cOpenApiMaybeOptionalInit\u003cPaths[Path], 'post'\u003e\u003e)\n    )\n\n    if (result?.error) {\n        const message =\n            typeof result.error === 'string' ? result.error : JSON.stringify(result.error)\n\n        throw new Error(message)\n    }\n\n    const data = result.data as { error?: unknown } | undefined\n    if (data?.error) {\n        const message = typeof data.error === 'string' ? data.error : JSON.stringify(data.error)\n\n        throw new Error(message)\n    }\n\n    if (!result.response.ok) {\n        throw new Error(`${result.response.status} ${result.response.statusText}`)\n    }\n\n    return result.data as OpenApiMethodResponse\u003ctypeof client, 'post', Path, Init\u003e\n}\n```\n\nNow you'll be able to\n- call **`rclone('config/listremotes')`** directly\n- get the data as the return value (correctly typed, and without having to de-construct the resulting object)\n- have it throw on error with a detailed error message (instead of checking the **`error`** field manually)\n\n## Contributing\n\nContributions = 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.\n\n\n\u003cdiv align=\"center\"\u003e\n\u003csub\u003eMade with ☁️ for the rclone community\u003c/sub\u003e\n\u003c/div\u003e","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frclone-ui%2Frclone-sdk","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Frclone-ui%2Frclone-sdk","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frclone-ui%2Frclone-sdk/lists"}