@robintech-seoul/robin-cloud-client
v0.1.0
Published
TypeScript client for Robin-Cloud storage and logs (X-Api-Key auth)
Readme
@robintech-seoul/robin-cloud-client
Robin-Cloud의 스토리지와 로그를 API 키 하나로 쓰는 TypeScript/JavaScript 클라이언트.
런타임 의존성 0개 — Node 18+ 내장 fetch만 쓴다. 브라우저 번들에서도 동작한다.
npm install @robintech-seoul/robin-cloud-client빠른 시작
import { RobinCloud } from "@robintech-seoul/robin-cloud-client";
const rc = new RobinCloud({
apiKey: "rbk_…", // 생략 시 process.env.ROBIN_CLOUD_API_KEY
project: "raxis", // 스토리지·로그 호출의 기본 프로젝트
});
// 업로드 (presign → S3 PUT → complete 3콜을 감싼다)
await rc.storage.upload("assets", "hello.txt", "hello world");
// 다운로드 (presign → S3 GET)
const bytes = await rc.storage.download("assets", "hello.txt");
console.log(new TextDecoder().decode(bytes));
// 로그
const sources = await rc.logs.sources();
const tail = await rc.logs.tail(sources[0].pod, { lines: 200 });인증
RobinCloud는 모든 BFF 요청에 X-Api-Key 헤더를 붙인다. 키는 콘솔에서 발급한
rbk_… 문자열이다. presigned S3 URL로 직접 나가는 업로드/다운로드 본문 전송에는
키를 붙이지 않는다 (presigned URL 자체가 자격증명).
| 설정 | 생성자 옵션 | 환경변수 | 기본값 |
|------|-------------|----------|--------|
| API 키 | apiKey | ROBIN_CLOUD_API_KEY | (필수) |
| 콘솔 호스트 | baseUrl | ROBIN_CLOUD_BASE_URL | https://console.robintech.cloud |
| 기본 프로젝트 | project | — | (호출별 지정 가능) |
| 타임아웃(ms) | timeoutMs | — | 30000 |
프로젝트는 클라이언트 기본값을 두고 호출별로 덮어쓸 수 있다:
await rc.storage.listBuckets({ project: "other-project" });스토리지
// 버킷
await rc.storage.listBuckets();
await rc.storage.createBucket("assets", { public: false });
await rc.storage.updateBucket("assets", { public: true });
await rc.storage.deleteBucket("assets", { force: true });
// 오브젝트
const { objects, folders, nextCursor } = await rc.storage.listObjects("assets", { prefix: "logs/" });
await rc.storage.upload("assets", "a/b.json", JSON.stringify({ ok: true }));
const bytes = await rc.storage.download("assets", "a/b.json");
await rc.storage.createFolder("assets", "reports");
await rc.storage.move("assets", { fromKey: "a/b.json", toKey: "a/c.json" });
await rc.storage.delete("assets", { keys: ["a/c.json"] });
// public 버킷의 무인증 URL (네트워크 호출 없이 조립만)
const url = rc.storage.publicUrl("assets", "logo.png");upload은 string | Uint8Array | ArrayBuffer를 받는다. content-type은 키 확장자로
추정하며 { contentType }으로 강제할 수 있다.
로그
const sources = await rc.logs.sources(); // [{ pod, status, containers }]
const text = await rc.logs.tail("web-abc123", { // 최근 N줄 (서버 상한 5000)
container: "app",
lines: 500,
});에러 처리
HTTP 상태코드가 계약이다. 4xx/5xx는 타입 있는 예외로 던져진다:
| 상태 | 예외 |
|------|------|
| 401 | AuthenticationError |
| 403 | PermissionDeniedError |
| 404 | NotFoundError |
| 409 | ConflictError |
| 413 | PayloadTooLargeError |
| 422 | ValidationError |
| 503 | ServiceUnavailableError |
모두 ApiError(→ RobinCloudError)를 상속하며 statusCode, message, body를 갖는다.
import { NotFoundError, ApiError } from "@robintech-seoul/robin-cloud-client";
try {
await rc.storage.download("assets", "missing.txt");
} catch (e) {
if (e instanceof NotFoundError) console.log("없음");
else if (e instanceof ApiError) console.log(e.statusCode, e.message);
}개발
npm install
npm run typecheck # tsc --noEmit
npm test # vitest (fetch 모킹, 네트워크 없음)
npm run build # tsup → dist (ESM + CJS + d.ts)