zenodo-utils
Version:
Utilities for working with zenodo
147 lines (146 loc) • 4.92 kB
JavaScript
import axios from 'axios';
import * as fs from 'fs';
import * as path from 'path';
export var UploadType;
(function (UploadType) {
/* publication */
UploadType["publication"] = "publication";
/* poster */
UploadType["poster"] = "poster";
/* presentation */
UploadType["presentation"] = "presentation";
/* dataset */
UploadType["dataset"] = "dataset";
/* image */
UploadType["image"] = "image";
/* video/audio */
UploadType["video"] = "video";
/* software */
UploadType["software"] = "software";
/* lesson */
UploadType["lesson"] = "lesson";
/* physical object */
UploadType["physicalobject"] = "physicalobject";
UploadType["other"] = "other";
})(UploadType || (UploadType = {}));
export var AccessRight;
(function (AccessRight) {
/* Open Access, the default */
AccessRight["open"] = "open";
/* Embargoed Access */
AccessRight["embargoed"] = "embargoed";
/* Restricted Access */
AccessRight["restricted"] = "restricted";
/* Closed Access */
AccessRight["closed"] = "closed";
})(AccessRight || (AccessRight = {}));
export class ZenodoClient {
constructor(accessToken, sandbox = false) {
this.baseURL = 'https://zenodo.org/api';
if (!accessToken) {
throw new Error('Cannot connect to zenodo without an access token.');
}
this.accessToken = accessToken;
if (sandbox) {
this.baseURL = 'https://sandbox.zenodo.org/api';
}
this.axiosInstance = axios.create({
baseURL: this.baseURL,
params: {
access_token: this.accessToken,
},
});
}
/**
* Create a new deposition with the provided metadata.
* @param metadata Deposition metadata
*/
async createDeposition(metadata) {
try {
const response = await this.axiosInstance.post('/deposit/depositions', { metadata }, {
headers: {
'Content-Type': 'application/json',
},
});
return response.data;
}
catch (error) {
this.handleError(error);
}
}
/**
* Upload a file to an existing deposition.
* @param depositionId ID of the deposition
* @param filePath Path to the file to upload
*/
async uploadFile(depositionId, filePath) {
try {
// Get the deposition to retrieve the bucket URL
const deposition = await this.axiosInstance.get(`/deposit/depositions/${depositionId}`);
const bucketUrl = deposition.data.links.bucket;
// Step 2: Prepare the file for upload
const fileName = path.basename(filePath);
const url = `${bucketUrl}/${encodeURIComponent(fileName)}`;
const fileStream = fs.createReadStream(filePath);
// Step 3: Calculate the file size
const stats = fs.statSync(filePath);
const fileSizeInBytes = stats.size;
// Step 4: Set the appropriate headers and config
const response = await axios.put(url, fileStream, {
headers: {
'Content-Type': 'application/octet-stream', // or the actual MIME type of your file
'Content-Length': fileSizeInBytes,
},
params: {
access_token: this.accessToken,
},
maxContentLength: Infinity,
maxBodyLength: Infinity,
});
return response.data;
}
catch (error) {
this.handleError(error);
}
}
/**
* List all files in an unpublished deposition.
* @param depositionId ID of the deposition
*/
async listFiles(depositionId) {
try {
const response = await this.axiosInstance.get(`/deposit/depositions/${depositionId}/files`);
return response.data;
}
catch (error) {
this.handleError(error);
}
}
/**
* Publish a deposition.
* @param depositionId ID of the deposition
*/
async publishDeposition(depositionId) {
try {
const response = await this.axiosInstance.post(`/deposit/depositions/${depositionId}/actions/publish`);
return response.data;
}
catch (error) {
this.handleError(error);
}
}
/**
* Handle API errors.
* @param error Error object
*/
handleError(error) {
if (error.response) {
console.error('API Error:', error.response.status, error.response.data);
throw new Error(`API Error: ${error.response.status} ${JSON.stringify(error.response.data)}`);
}
else {
console.error('Error:', error.message);
throw new Error(`Error: ${error.message}`);
}
}
}