@eleven-am/nestjs-storage
Version:
A NestJS module for uploading files to cloud storage providers
233 lines • 8.27 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.GDriveStorage = void 0;
const baseStorage_1 = require("./baseStorage");
const googleapis_1 = require("googleapis");
class GDriveStorage extends baseStorage_1.BaseStorage {
constructor(options) {
super(options.provider);
const auth = new googleapis_1.google.auth.OAuth2(options.options.clientId, options.options.clientSecret);
auth.setCredentials({
refresh_token: options.options.refreshToken,
});
this.drive = googleapis_1.google.drive({ version: 'v3', auth: auth });
}
createFolder(path) {
return new Promise((resolve, reject) => {
this.drive.files
.create({
resource: {
name: path,
mimeType: 'application/vnd.google-apps.folder',
},
fields: 'id, name, size, parents, modifiedTime, mimeType, contentHints/thumbnail, videoMediaMetadata, thumbnailLink, explicitlyTrashed',
}, (err, data) => {
if (err) {
reject(err);
}
else {
resolve(this.parseFile(data.data));
}
})
.catch(reject);
});
}
deleteFileOrFolder(fileId) {
return new Promise((resolve, reject) => {
this.drive.files.delete({
fileId: fileId,
supportsAllDrives: true,
}, (err) => {
if (err) {
reject(err);
}
else {
resolve(true);
}
});
});
}
getFileOrFolder(fileId) {
return new Promise((resolve, reject) => {
this.drive.files.get({
fileId: fileId,
supportsAllDrives: true,
fields: 'id, name, size, parents, modifiedTime, mimeType, contentHints/thumbnail, videoMediaMetadata, thumbnailLink, explicitlyTrashed',
}, (err, data) => {
if (err) {
reject(err);
}
else if (data?.data) {
resolve(this.parseFile(data.data));
}
else {
reject(new Error('File not found'));
}
});
});
}
moveFileOrFolder(fileId, newPath) {
return new Promise((resolve, reject) => {
this.drive.files.update({
fileId: fileId,
supportsAllDrives: true,
addParents: newPath,
removeParents: 'root',
fields: 'id, name, size, parents, modifiedTime, mimeType, contentHints/thumbnail, videoMediaMetadata, thumbnailLink, explicitlyTrashed',
}, (err, data) => {
if (err) {
reject(err);
}
else if (data?.data) {
resolve(this.parseFile(data.data));
}
else {
reject(new Error('File not found'));
}
});
});
}
putFile(path, data) {
return new Promise((resolve, reject) => {
this.drive.files
.create({
resource: {
name: path,
parents: ['root'],
},
media: {
mimeType: 'application/octet-stream',
body: data,
},
fields: 'id, name, size, parents, modifiedTime, mimeType, contentHints/thumbnail, videoMediaMetadata, thumbnailLink, explicitlyTrashed',
}, (err, data) => {
if (err) {
reject(err);
}
else {
resolve(this.parseFile(data.data));
}
})
.catch(reject);
});
}
readFile(fileId) {
return new Promise((resolve, reject) => {
this.drive.files
.get({
fileId: fileId,
alt: 'media',
supportsAllDrives: true,
}, {
responseType: 'stream',
})
.then((res) => res.data)
.catch(reject);
});
}
readFolder(folderId) {
return this.readFolderRecursive(folderId);
}
renameFileOrFolder(fileId, newName) {
return new Promise((resolve, reject) => {
this.drive.files
.update({
fileId: fileId,
requestBody: {
name: newName,
},
fields: 'id, name, size, parents, modifiedTime, mimeType, contentHints/thumbnail, videoMediaMetadata, thumbnailLink, explicitlyTrashed',
})
.then((res) => resolve(this.parseFile(res.data)))
.catch(reject);
});
}
getSignedUrl(fileId) {
return new Promise((resolve, reject) => {
this.drive.files
.get({
fileId: fileId,
supportsAllDrives: true,
fields: 'id, name, size, parents, modifiedTime, mimeType',
})
.then((res) => resolve(res.data.webContentLink || ''))
.catch(reject);
});
}
streamFile(fileId, range) {
return new Promise((resolve, reject) => {
this.drive.files
.get({
fileId: fileId,
alt: 'media',
supportsAllDrives: true,
}, {
responseType: 'stream',
headers: {
Range: range,
},
})
.then((res) => {
resolve({
stream: res.data,
headers: {
contentLength: res.headers['content-length'],
contentType: res.headers['content-type'],
contentRange: res.headers['content-range'],
contentDisposition: res.headers['content-disposition'],
},
});
})
.catch(reject);
});
}
readRootFolder() {
return this.readFolder('root');
}
parseFile(file) {
if (file.id === undefined) {
throw new Error('File id is undefined');
}
if (file.name === undefined) {
throw new Error('File name is undefined');
}
return {
name: file.name || '',
path: file.id || '',
size: Number(file.size) || 0,
mimeType: file.mimeType || null,
isFolder: file.mimeType === 'application/vnd.google-apps.folder',
modifiedAt: new Date(file.modifiedTime || 0),
};
}
readFolderRecursive(folderId, pageToken) {
return new Promise((resolve, reject) => {
this.drive.files.list({
q: `'${folderId}' in parents and trashed = false`,
fields: 'nextPageToken, files(id, name, size, parents, modifiedTime, mimeType, contentHints/thumbnail, videoMediaMetadata, thumbnailLink, explicitlyTrashed)',
supportsAllDrives: true,
pageToken: pageToken,
spaces: 'drive',
orderBy: 'name',
pageSize: 1000,
}, (err, data) => {
if (err) {
reject(err);
}
else {
const files = data?.data.files?.map((file) => this.parseFile(file)) || [];
if (data?.data.nextPageToken) {
this.readFolderRecursive(folderId, data.data.nextPageToken)
.then((nextFiles) => resolve([...files, ...nextFiles]))
.catch(reject);
}
else {
resolve(files);
}
}
});
});
}
}
exports.GDriveStorage = GDriveStorage;
//# sourceMappingURL=gDriveStorage.js.map