zenodo-utils
Version:
Utilities for working with zenodo
158 lines (157 loc) • 5.04 kB
JavaScript
import axios from 'axios';
import * as fs from 'fs';
import * as path from 'path';
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 createEmptyDeposition() {
try {
const response = await this.axiosInstance.post('/deposit/depositions', {}, {
headers: {
'Content-Type': 'application/json',
},
});
return response.data;
}
catch (error) {
this.handleError(error);
}
}
/**
* 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);
}
}
/**
* Get a deposition by ID.
* @param depositionId ID of the deposition
*/
async getDeposition(depositionId) {
try {
const response = await this.axiosInstance.get(`/deposit/depositions/${depositionId}`);
return response.data;
}
catch (error) {
this.handleError(error);
}
}
/**
* Create a new deposition with the provided metadata.
* @param metadata Deposition metadata
*/
async updateDeposition(depositionId, metadata) {
try {
const response = await this.axiosInstance.put(`/deposit/depositions/${depositionId}`, { 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(bucketUrl, filePath) {
try {
// Prepare the file for upload
const fileName = path.basename(filePath);
const url = `${bucketUrl}/${encodeURIComponent(fileName)}`;
const fileStream = fs.createReadStream(filePath);
// Calculate the file size
const stats = fs.statSync(filePath);
const fileSizeInBytes = stats.size;
// 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}`);
}
}
}