dilnaka
v0.0.3
Published
TypeScript SDK for Dilnaka file uploads
Maintainers
Readme
Dilnaka TypeScript SDK
TypeScript SDK for uploading files through the Dilnaka Upload API.
The SDK uses the fixed Dilnaka API base URL https://dilnaka.storage.tsnc.tech. It reads the API key and timeout from explicit constructor options first, then environment variables. It requests a presigned S3 upload URL from your Dilnaka backend, uploads the file directly to S3, and calls the completion endpoint.
Small files use a single presigned PUT. Large files (at or above multipartThreshold, 100 MB by default) automatically use a resumable S3 multipart upload that streams the file in chunks and retries a failed part instead of discarding the whole transfer.
Install
npm install dilnakaConfigure
You can pass configuration directly to new Dilnaka(...), or set environment variables for your application.
Configuration precedence is:
- Explicit constructor options such as
new Dilnaka({ apiKey: "...", timeout: 30 }) - Existing process environment variables such as
DILNAKA_TIMEOUT - Values loaded from
.env - Built-in defaults
If you use a .env file, create it in your application project:
DILNAKA_API_KEY=dlk_dev_your_api_key_here
DILNAKA_TIMEOUT=60
DILNAKA_MULTIPART_THRESHOLD=104857600
DILNAKA_UPLOAD_TIMEOUT=300The SDK always uses https://dilnaka.storage.tsnc.tech as its base URL.
DILNAKA_TIMEOUT(default60): timeout in seconds for JSON API calls (presign, complete, list, etc.).DILNAKA_MULTIPART_THRESHOLD(default104857600, i.e. 100 MB): files at or above this size use the multipart flow.DILNAKA_UPLOAD_TIMEOUT(default300): per-request transfer timeout in seconds for the singlePUTor each multipart part. This is deliberately larger thanDILNAKA_TIMEOUTso large chunks over slow links do not time out.
Basic upload
import { Dilnaka } from "dilnaka";
const client = new Dilnaka();
const uploaded = await client.upload("./test-upload.txt");
console.log(uploaded.id);
console.log(uploaded.key);
console.log(uploaded.status);Explicit configuration
import { Dilnaka } from "dilnaka";
const client = new Dilnaka({
apiKey: "dlk_dev_your_api_key_here"
});
const uploaded = await client.upload("./avatar.png", {
folder: "avatars"
});
console.log(uploaded);Large file uploads
upload(...) picks the transfer strategy automatically based on file size, so the
call is identical for small and large files:
import { Dilnaka } from "dilnaka";
const client = new Dilnaka();
// Uses multipart automatically when the file is >= the threshold (100 MB default).
const uploaded = await client.upload("./course-bundle.zip");
console.log(uploaded.id, uploaded.status);You can tune the behavior per call or per client:
// Force multipart for anything over 25 MB and give each part 10 minutes.
const uploaded = await client.upload("./course-bundle.zip", {
multipartThreshold: 25 * 1024 * 1024,
uploadTimeout: 600
});The lower-level multipart methods are also available if you need direct control:
createMultipartUpload(...), presignMultipartParts(...),
completeMultipartUpload(...), and abortMultipartUpload(...). A failed multipart
transfer is aborted automatically so it does not leave a dangling upload on the
bucket.
Request a file access URL
Use getFileAccessUrl(...) when you need a URL for downloading or opening a file.
import { Dilnaka } from "dilnaka";
const client = new Dilnaka();
const access = await client.getFileAccessUrl("file_123");
console.log(access.fileId);
console.log(access.url);
console.log(access.expiresIn);
console.log(access.isTemporary);Pass expiresIn to request a temporary URL from the backend:
const temporaryAccess = await client.getFileAccessUrl("file_123", 600);
console.log(temporaryAccess.url);
console.log(temporaryAccess.expiresIn); // 600
console.log(temporaryAccess.isTemporary); // trueexpiresIn must be greater than 0. If you omit it, the SDK requests the default access URL returned by your backend.
The method returns a FileAccessUrl object with:
fileId: Dilnaka file IDurl: Access URL returned by the APIexpiresIn: Expiration time in seconds when the backend returns a temporary URLisTemporary:truewhen the backend marks the URL as temporary, or when an expiration is present
API
const client = new Dilnaka({
apiKey?: string;
timeout?: number;
envFile?: string;
fetch?: typeof fetch;
multipartThreshold?: number;
uploadTimeout?: number;
});Available methods:
upload(filePath, options?)createPresignedUpload(options)completeUpload(fileId)createMultipartUpload(options)presignMultipartParts(fileId, partNumbers)completeMultipartUpload(fileId, parts)abortMultipartUpload(fileId)listFiles()getFile(fileId)getFileAccessUrl(fileId, expiresIn?)deleteFile(fileId)
Python-style aliases are also available for migration convenience:
create_presigned_upload(...)complete_upload(...)create_multipart_upload(...)presign_multipart_parts(...)complete_multipart_upload(...)abort_multipart_upload(...)list_files()get_file(...)get_file_access_url(...)delete_file(...)
Expected backend endpoints
The SDK expects your Caspian backend to expose:
POST /v1/uploads/presign
POST /v1/uploads/complete
POST /v1/uploads/multipart/create
POST /v1/uploads/multipart/parts
POST /v1/uploads/multipart/complete
POST /v1/uploads/multipart/abort
GET /v1/files
GET /v1/files/{file_id}
GET /v1/files/{file_id}/access-url
DELETE /v1/files/{file_id}When a temporary URL is requested, the SDK sends:
GET /v1/files/{file_id}/access-url?expiresIn=600Security model
The SDK never receives AWS credentials. It only receives a temporary presigned upload URL from your Dilnaka backend.
Your backend remains responsible for API key validation, scope checking, file validation, S3 key generation, metadata persistence, and upload completion verification.
