mirror of
https://github.com/Portabase/portabase.git
synced 2026-07-14 11:16:13 +02:00
Merge branch 'dev' into feat/oidc
This commit is contained in:
@@ -1,141 +1,161 @@
|
||||
"use server"
|
||||
import {mkdir, unlink} from 'fs/promises';
|
||||
import path from 'path';
|
||||
import {StorageDeleteInput, StorageGetInput, StorageMetaData, StorageResult, StorageUploadInput} from '../types';
|
||||
"use server";
|
||||
import { mkdir, unlink } from "fs/promises";
|
||||
import path from "path";
|
||||
import {
|
||||
StorageDeleteInput,
|
||||
StorageGetInput,
|
||||
StorageMetaData,
|
||||
StorageResult,
|
||||
StorageUploadInput,
|
||||
} from "../types";
|
||||
import fs from "node:fs";
|
||||
import {generateFileUrl} from "@/features/storages/helpers";
|
||||
import {Readable} from "node:stream";
|
||||
import {env} from "@/env.mjs";
|
||||
import { generateFileUrl } from "@/features/storages/helpers";
|
||||
import { Readable } from "node:stream";
|
||||
import { env } from "@/env.mjs";
|
||||
|
||||
const BASE_DIR = path.join(env.PRIVATE_PATH, '/uploads')
|
||||
const BASE_DIR = path.join(env.PRIVATE_PATH, "/uploads");
|
||||
|
||||
export async function uploadLocal(
|
||||
config: { baseDir?: string },
|
||||
input: { data: StorageUploadInput; metadata?: StorageMetaData }
|
||||
config: { baseDir?: string },
|
||||
input: { data: StorageUploadInput; metadata?: StorageMetaData },
|
||||
): Promise<StorageResult> {
|
||||
const base = config.baseDir ? path.join(process.cwd(), config.baseDir ?? "") : BASE_DIR;
|
||||
const base = config.baseDir
|
||||
? path.join(process.cwd(), config.baseDir ?? "")
|
||||
: BASE_DIR;
|
||||
|
||||
const fullPath = path.join(base, input.data.path);
|
||||
const dir = path.dirname(fullPath);
|
||||
const fullPath = path.join(base, input.data.path);
|
||||
const dir = path.dirname(fullPath);
|
||||
|
||||
await mkdir(dir, { recursive: true });
|
||||
await mkdir(dir, { recursive: true });
|
||||
|
||||
try {
|
||||
const file = input.data.file;
|
||||
if (Buffer.isBuffer(file)) {
|
||||
await fs.promises.writeFile(fullPath, input.data.file);
|
||||
} else if (file instanceof Readable) {
|
||||
await new Promise<void>((resolve, reject) => {
|
||||
const writable = fs.createWriteStream(fullPath);
|
||||
file.pipe(writable);
|
||||
writable.on("finish", resolve);
|
||||
writable.on("error", reject);
|
||||
});
|
||||
} else {
|
||||
return { success: false, provider: "local", error: "Unsupported file type. Must be Buffer or ReadableStream" };
|
||||
}
|
||||
|
||||
if (input.data.url) {
|
||||
const url = await generateFileUrl(input);
|
||||
if (!url) {
|
||||
return { success: false, provider: "local", response: "Unable to get URL" };
|
||||
}
|
||||
return { success: true, provider: "local", url };
|
||||
}
|
||||
|
||||
return { success: true, provider: "local" };
|
||||
} catch (err: any) {
|
||||
try { await unlink(fullPath); } catch {}
|
||||
return { success: false, provider: "local", error: err.message || "Upload failed" };
|
||||
try {
|
||||
const file = input.data.file;
|
||||
if (Buffer.isBuffer(file)) {
|
||||
await fs.promises.writeFile(fullPath, input.data.file);
|
||||
} else if (file instanceof Readable) {
|
||||
await new Promise<void>((resolve, reject) => {
|
||||
const writable = fs.createWriteStream(fullPath);
|
||||
file.pipe(writable);
|
||||
writable.on("finish", resolve);
|
||||
writable.on("error", reject);
|
||||
});
|
||||
} else {
|
||||
return {
|
||||
success: false,
|
||||
provider: "local",
|
||||
error: "Unsupported file type. Must be Buffer or ReadableStream",
|
||||
};
|
||||
}
|
||||
|
||||
if (input.data.url) {
|
||||
const url = await generateFileUrl(input);
|
||||
if (!url) {
|
||||
return {
|
||||
success: false,
|
||||
provider: "local",
|
||||
response: "Unable to get URL",
|
||||
};
|
||||
}
|
||||
return { success: true, provider: "local", url };
|
||||
}
|
||||
|
||||
return { success: true, provider: "local" };
|
||||
} catch (err: any) {
|
||||
try {
|
||||
await unlink(fullPath);
|
||||
} catch {}
|
||||
return {
|
||||
success: false,
|
||||
provider: "local",
|
||||
error: err.message || "Upload failed",
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
export async function getLocal(
|
||||
config: { baseDir?: string },
|
||||
input: { data: StorageGetInput; metadata: StorageMetaData }
|
||||
config: { baseDir?: string },
|
||||
input: { data: StorageGetInput; metadata: StorageMetaData },
|
||||
): Promise<StorageResult> {
|
||||
const base = config.baseDir
|
||||
? path.join(process.cwd(), config.baseDir ?? "")
|
||||
: BASE_DIR;
|
||||
const filePath = path.join(base, input.data.path);
|
||||
|
||||
const base = config.baseDir ? path.join(process.cwd(), config.baseDir ?? "") : BASE_DIR;
|
||||
const filePath = path.join(base, input.data.path);
|
||||
if (!fs.existsSync(filePath)) {
|
||||
console.error("File not found at:", filePath);
|
||||
return {
|
||||
success: false,
|
||||
provider: "local",
|
||||
error: "File not found",
|
||||
};
|
||||
}
|
||||
|
||||
if (!fs.existsSync(filePath)) {
|
||||
console.error("File not found at:", filePath);
|
||||
return {
|
||||
success: false,
|
||||
provider: "local",
|
||||
error: "File not found",
|
||||
};
|
||||
}
|
||||
let fileStream: fs.ReadStream | undefined;
|
||||
|
||||
let fileStream: fs.ReadStream | undefined;
|
||||
try {
|
||||
fileStream = fs.createReadStream(filePath);
|
||||
} catch (err: any) {
|
||||
console.error("Error creating read stream:", err);
|
||||
return {
|
||||
success: false,
|
||||
provider: "local",
|
||||
error: err.message,
|
||||
};
|
||||
}
|
||||
|
||||
try {
|
||||
fileStream = fs.createReadStream(filePath);
|
||||
} catch (err: any) {
|
||||
console.error("Error creating read stream:", err);
|
||||
return {
|
||||
success: false,
|
||||
provider: "local",
|
||||
error: err.message,
|
||||
};
|
||||
}
|
||||
|
||||
if (input.data.signedUrl) {
|
||||
const url = await generateFileUrl(input);
|
||||
if (!url) {
|
||||
return {
|
||||
success: false,
|
||||
provider: "local",
|
||||
error: "Unable to generate signed URL",
|
||||
};
|
||||
}
|
||||
|
||||
return {
|
||||
success: true,
|
||||
provider: "local",
|
||||
file: fileStream,
|
||||
url,
|
||||
};
|
||||
if (input.data.signedUrl) {
|
||||
const url = await generateFileUrl(input);
|
||||
if (!url) {
|
||||
return {
|
||||
success: false,
|
||||
provider: "local",
|
||||
error: "Unable to generate signed URL",
|
||||
};
|
||||
}
|
||||
|
||||
return {
|
||||
success: true,
|
||||
provider: "local",
|
||||
file: fileStream,
|
||||
success: true,
|
||||
provider: "local",
|
||||
file: fileStream,
|
||||
url,
|
||||
};
|
||||
}
|
||||
|
||||
return {
|
||||
success: true,
|
||||
provider: "local",
|
||||
file: fileStream,
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
|
||||
export async function deleteLocal(
|
||||
config: { baseDir?: string },
|
||||
input: { data: StorageDeleteInput, metadata?: StorageMetaData }
|
||||
config: { baseDir?: string },
|
||||
input: { data: StorageDeleteInput; metadata?: StorageMetaData },
|
||||
): Promise<StorageResult> {
|
||||
const base = config.baseDir
|
||||
? path.join(process.cwd(), config.baseDir ?? "")
|
||||
: BASE_DIR;
|
||||
const fullPath = path.join(base, input.data.path);
|
||||
|
||||
const base = config.baseDir ? path.join(process.cwd(), config.baseDir ?? "") : BASE_DIR;
|
||||
const fullPath = path.join(base, input.data.path);
|
||||
|
||||
await unlink(fullPath);
|
||||
return {
|
||||
success: true,
|
||||
provider: 'local',
|
||||
};
|
||||
await unlink(fullPath);
|
||||
return {
|
||||
success: true,
|
||||
provider: "local",
|
||||
};
|
||||
}
|
||||
|
||||
export async function pingLocal(
|
||||
config: { baseDir?: string }
|
||||
): Promise<StorageResult> {
|
||||
export async function pingLocal(config: {
|
||||
baseDir?: string;
|
||||
}): Promise<StorageResult> {
|
||||
const base = path.join(process.cwd(), config.baseDir ?? "") || BASE_DIR;
|
||||
const fullPath = path.join(base, "ping.txt");
|
||||
|
||||
const base = path.join(process.cwd(), config.baseDir ?? "") || BASE_DIR;
|
||||
const fullPath = path.join(base, "ping.txt");
|
||||
|
||||
await fs.promises.writeFile(fullPath, "ping");
|
||||
await fs.promises.readFile(fullPath);
|
||||
await fs.promises.unlink(fullPath);
|
||||
return {
|
||||
success: true,
|
||||
provider: 'local',
|
||||
response: "Local storage OK"
|
||||
};
|
||||
|
||||
}
|
||||
await fs.promises.writeFile(fullPath, "ping");
|
||||
await fs.promises.readFile(fullPath);
|
||||
await fs.promises.unlink(fullPath);
|
||||
return {
|
||||
success: true,
|
||||
provider: "local",
|
||||
response: "Local storage OK",
|
||||
};
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user