Import source: backend/src/utils/gdrive
Import the existing local project snapshot. This commit organizes existing files; it does not represent newly developed functionality.
This commit is contained in:
@@ -0,0 +1,69 @@
|
|||||||
|
import { google } from 'googleapis';
|
||||||
|
import type { Readable } from 'node:stream';
|
||||||
|
import { env } from '../config/env.js';
|
||||||
|
|
||||||
|
const auth = new google.auth.OAuth2(env.gdriveClientId, env.gdriveClientSecret);
|
||||||
|
auth.setCredentials({ refresh_token: env.gdriveRefreshToken });
|
||||||
|
|
||||||
|
const drive = google.drive({ version: 'v3', auth });
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Upload a stream directly to Google Drive.
|
||||||
|
* Uses the Drive API's resumable upload — no rclone process, no disk writes.
|
||||||
|
* Returns the new file's Drive ID.
|
||||||
|
*/
|
||||||
|
export async function uploadStream(
|
||||||
|
stream: Readable,
|
||||||
|
filename: string,
|
||||||
|
mimeType: string,
|
||||||
|
): Promise<string> {
|
||||||
|
const res = await drive.files.create({
|
||||||
|
requestBody: {
|
||||||
|
name: filename,
|
||||||
|
parents: [env.gdriveFolderId],
|
||||||
|
},
|
||||||
|
media: {
|
||||||
|
mimeType: mimeType || 'application/octet-stream',
|
||||||
|
body: stream,
|
||||||
|
},
|
||||||
|
fields: 'id',
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!res.data.id) throw new Error('GDrive upload returned no file ID');
|
||||||
|
return res.data.id;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Stream file content from Drive for inline preview.
|
||||||
|
* Returns a readable stream — no disk writes on the server.
|
||||||
|
*/
|
||||||
|
export async function getStream(fileId: string): Promise<Readable> {
|
||||||
|
const res = await drive.files.get(
|
||||||
|
{ fileId, alt: 'media' },
|
||||||
|
{ responseType: 'stream' },
|
||||||
|
);
|
||||||
|
return res.data as unknown as Readable;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Permanently delete a file from Drive. Silently ignores 404. */
|
||||||
|
export async function deleteFile(fileId: string): Promise<void> {
|
||||||
|
await drive.files.delete({ fileId }).catch((err: { code?: number }) => {
|
||||||
|
if (err.code !== 404) throw err;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Direct download URL — bypasses Drive's antivirus interstitial for large files. */
|
||||||
|
export function downloadUrl(fileId: string): string {
|
||||||
|
return `https://drive.usercontent.google.com/download?id=${fileId}&export=download&confirm=t`;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Lightweight connectivity check: lists 1 file in our folder. Returns false on any error. */
|
||||||
|
export async function checkGdriveHealth(): Promise<boolean> {
|
||||||
|
if (!env.gdriveClientId) return false;
|
||||||
|
try {
|
||||||
|
await drive.files.list({ q: `'${env.gdriveFolderId}' in parents`, pageSize: 1, fields: 'files(id)' });
|
||||||
|
return true;
|
||||||
|
} catch {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user