Node.js
Simple JavaScript (Node.js) script to upload a capture zip file.
It retrieves an authentication token using the client_id
and client_secret
found in your Developer Dashboard.
Read the Quick Start Guide and the Upload Captures pages to learn more.
⚠️ To run this you need Node.js 18+ (for native
fetch
andFormData
support). Install dependencies if needed:npm install node-fetch
import fs from "fs";
import path from "path";
import fetch from "node-fetch"; // Node 18+ users can omit this import
const CLIENT_ID = "insert-it-here";
const CLIENT_SECRET = "insert-it-here";
const AUTH_ENDPOINT = "https://signin.teleport.varjo.com/oauth2/token";
const API_BASE = "https://teleport.varjo.com";
async function main() {
const filename = process.argv[2];
if (!filename) {
console.error("Usage: node upload_capture.js <file>");
process.exit(1);
}
const filePath = path.resolve(filename);
const bytesize = fs.statSync(filePath).size;
console.log(`Uploading capture of ${bytesize} bytes...`);
// Step 1: Authenticate
const authResponse = await fetch(AUTH_ENDPOINT, {
method: "POST",
headers: { "Content-Type": "application/x-www-form-urlencoded" },
body: new URLSearchParams({
grant_type: "client_credentials",
client_id: CLIENT_ID,
client_secret: CLIENT_SECRET,
scope: "openid profile email",
}),
});
if (!authResponse.ok) {
console.error("Authentication failed:", authResponse.status);
process.exit(1);
}
const { access_token } = await authResponse.json();
// Step 2: Create capture
const created = await fetch(`${API_BASE}/api/v1/captures`, {
method: "POST",
headers: {
Authorization: `Bearer ${access_token}`,
"Content-Type": "application/json",
},
body: JSON.stringify({
name: path.basename(filePath),
bytesize,
input_data_format: "bulk-images",
}),
});
if (!created.ok) {
console.error("Failed to create capture:", created.status);
process.exit(1);
}
const { eid, num_parts, chunk_size } = await created.json();
console.log(`Uploading ${num_parts} parts...`);
// Step 3: Upload file parts
const fd = fs.openSync(filePath, "r");
const parts = [];
for (let part_no = 1; part_no <= num_parts; part_no++) {
const urlResp = await fetch(
`${API_BASE}/api/v1/captures/${eid}/create-upload-url/${part_no}`,
{
method: "POST",
headers: {
Authorization: `Bearer ${access_token}`,
"Content-Type": "application/json",
},
body: JSON.stringify({ eid, bytesize }),
}
);
if (!urlResp.ok) {
console.error(`Failed to get upload URL for part ${part_no}`);
process.exit(1);
}
const { upload_url } = await urlResp.json();
// Read a chunk from the file
const buffer = Buffer.alloc(chunk_size);
const bytesRead = fs.readSync(fd, buffer, 0, chunk_size, null);
const chunk = buffer.subarray(0, bytesRead);
console.log(`Uploading part ${part_no}...`);
const putResp = await fetch(upload_url, {
method: "PUT",
body: chunk,
});
if (!putResp.ok) {
console.error(`Failed to upload part ${part_no}:`, putResp.status);
process.exit(1);
}
const etag = putResp.headers.get("etag").replace(/"/g, "");
parts.push({ number: part_no, etag });
}
fs.closeSync(fd);
// Step 4: Complete upload
const completed = await fetch(`${API_BASE}/api/v1/captures/${eid}/uploaded`, {
method: "POST",
headers: {
Authorization: `Bearer ${access_token}`,
"Content-Type": "application/json",
},
body: JSON.stringify({ eid, parts }),
});
if (!completed.ok) {
console.error("Failed to finalize upload:", completed.status);
process.exit(1);
}
const { state } = await completed.json();
console.log("Upload done!");
console.log("Capture state:", state);
}
main().catch((err) => {
console.error("Error:", err);
process.exit(1);
});