feat: initial commit — site + admin panel + Postgres content pipeline
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,84 @@
|
||||
// server/publish.mjs — "Yayınla" pipeline: DB -> JSON files -> vite-ssg build -> dist swap
|
||||
import fs from "node:fs";
|
||||
import path from "node:path";
|
||||
import { spawn } from "node:child_process";
|
||||
import { fileURLToPath } from "node:url";
|
||||
import { exportToFiles } from "./db.mjs";
|
||||
|
||||
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
||||
const ROOT = path.resolve(__dirname, "..");
|
||||
export const DIST_DIR = path.join(ROOT, "dist");
|
||||
const STAGING_DIR = path.join(ROOT, ".dist-staging");
|
||||
const LOG_LIMIT = 60_000;
|
||||
|
||||
const job = {
|
||||
running: false,
|
||||
startedAt: null,
|
||||
finishedAt: null,
|
||||
ok: null,
|
||||
log: "",
|
||||
};
|
||||
|
||||
function append(text) {
|
||||
job.log = (job.log + text).slice(-LOG_LIMIT);
|
||||
}
|
||||
|
||||
function run(cmd, args, opts = {}) {
|
||||
return new Promise((resolve, reject) => {
|
||||
const child = spawn(cmd, args, {
|
||||
cwd: ROOT,
|
||||
env: { ...process.env, ...opts.env },
|
||||
shell: false,
|
||||
});
|
||||
child.stdout.on("data", (d) => append(d.toString()));
|
||||
child.stderr.on("data", (d) => append(d.toString()));
|
||||
child.on("error", reject);
|
||||
child.on("close", (code) => {
|
||||
code === 0
|
||||
? resolve()
|
||||
: reject(new Error(`${cmd} exited with code ${code}`));
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
export function getPublishState() {
|
||||
return { ...job };
|
||||
}
|
||||
|
||||
// Kick off the publish pipeline in the background. Returns false if already running.
|
||||
export function startPublish() {
|
||||
if (job.running) return false;
|
||||
job.running = true;
|
||||
job.ok = null;
|
||||
job.log = "";
|
||||
job.startedAt = new Date().toISOString();
|
||||
job.finishedAt = null;
|
||||
|
||||
(async () => {
|
||||
try {
|
||||
append("[1/3] DB → JSON dosyaları aktarılıyor...\n");
|
||||
const written = await exportToFiles();
|
||||
append(` ${written.length} dosya yazıldı\n`);
|
||||
|
||||
append("[2/3] Site build ediliyor (vite-ssg)...\n");
|
||||
fs.rmSync(STAGING_DIR, { recursive: true, force: true });
|
||||
await run("npx", ["vite-ssg", "build"], {
|
||||
env: { BUILD_OUT_DIR: STAGING_DIR },
|
||||
});
|
||||
|
||||
append("[3/3] dist güncelleniyor...\n");
|
||||
fs.rmSync(DIST_DIR, { recursive: true, force: true });
|
||||
fs.renameSync(STAGING_DIR, DIST_DIR);
|
||||
append("Tamamlandı ✓\n");
|
||||
job.ok = true;
|
||||
} catch (e) {
|
||||
append(`\nHATA: ${e.message}\n`);
|
||||
job.ok = false;
|
||||
} finally {
|
||||
job.running = false;
|
||||
job.finishedAt = new Date().toISOString();
|
||||
}
|
||||
})();
|
||||
|
||||
return true;
|
||||
}
|
||||
Reference in New Issue
Block a user