prasi-bun/app/srv/api/site-export.ts

142 lines
3.7 KiB
TypeScript

import { apiContext } from "../../../pkgs/core/server/api/api-ctx";
import { dir } from "dir";
import fs from "fs";
import { exists } from "fs-jetpack";
import { gzipSync } from "zlib";
import path from "path";
import { g } from "utils/global";
import { buildNpm } from "../util/build-npm";
export const _ = {
url: "/site-export/:site_id",
async api(site_id: string) {
const { req, res } = apiContext(this);
const site = (await _db.site.findFirst({
where: { id: site_id },
})) as any;
const pages = await _db.page.findMany({
where: {
id_site: site_id,
is_deleted: false,
name: { not: { startsWith: "layout:" } },
},
});
if (site) {
const layout = await _db.page.findFirst({
where: {
id_site: site.id,
name: { startsWith: "layout:" },
is_default_layout: true,
is_deleted: false,
},
select: { content_tree: true, id: true },
});
const cgroups = await _db.site_use_comp.findMany({
where: { id_site: site.id },
});
if (Array.isArray(cgroups)) {
site.cgroup_ids = [];
for (const id of cgroups.map((c) => c.use_id_site)) {
site.cgroup_ids.push(id);
}
}
if (layout) {
const childs = (layout.content_tree as any).childs;
if (childs && childs.length > 0) {
(site as any).layout = childs[0];
(site as any).layout_id = layout.id;
}
}
}
const comps = await _db.component.findMany({
where: {
component_group: {
component_site: {
some: {
id_site: site_id,
},
},
},
},
});
const npm = {
site: {} as Record<string, string>,
pages: {} as Record<string, Record<string, string>>,
};
const page_ids = await _db.page.findMany({
where: { id_site: site_id, is_deleted: false },
select: { id: true },
});
const npm_page = await _db.npm_page.findMany({
where: { id_page: { in: page_ids.map((e) => e.id) } },
});
if (!exists(dir.data(`/npm/site/${site_id}`))) {
await buildNpm({ id: site_id, mode: "site" });
}
const npm_page_ids = {} as Record<string, any[]>;
for (const np of npm_page) {
if (!npm_page_ids[np.id_page]) {
npm_page_ids[np.id_page] = [];
}
npm_page_ids[np.id_page].push(np);
}
for (const [k, v] of Object.entries(npm_page_ids)) {
if (!exists(dir.data(`/npm/page/${k}`))) {
await buildNpm({ id: k, mode: "page", _items: v });
}
}
npm.site = readDirectoryRecursively(
dir.data(`/npm/site/${site_id}`)
);
for (const page of pages) {
if (exists(dir.data(`/npm/page/${page.id}`))) {
npm.pages[page.id] = readDirectoryRecursively(
dir.data(`/npm/page/${page.id}`)
);
}
}
const str = gzipSync(JSON.stringify({ site, pages, npm, comps }));
res.send(str);
},
};
export function readDirectoryRecursively(
dirPath: string,
baseDir?: string[]
): Record<string, string> {
const result: Record<string, string> = {};
const contents = fs.readdirSync(dirPath);
for (const item of contents) {
const itemPath = path.join(dirPath, item);
const stats = fs.statSync(itemPath);
if (stats.isFile()) {
const content = fs.readFileSync(itemPath, "utf-8");
result[[...(baseDir || []), item].join("/")] = content;
} else if (stats.isDirectory()) {
if (item !== "node_modules") {
const subdirResult = readDirectoryRecursively(itemPath, [
...(baseDir || []),
item,
]);
Object.assign(result, subdirResult);
}
}
}
return result;
}