diff --git a/app/srv/api/prod-zip.ts b/app/srv/api/prod-zip.ts new file mode 100644 index 00000000..e8c298bb --- /dev/null +++ b/app/srv/api/prod-zip.ts @@ -0,0 +1,69 @@ +import { apiContext } from "service-srv"; +import { code } from "../ws/sync/editor/code/util-code"; +import fs from "fs"; +import path from "path"; +import { gzipAsync } from "../ws/sync/entity/zlib"; +import { validate } from "uuid"; + +export const _ = { + url: "/prod-zip/:site_id", + async api(site_id: string) { + const { req, res } = apiContext(this); + + if (validate(site_id)) { + const result = { + pages: await _db.page.findMany({ + where: { id_site: site_id, is_deleted: false }, + select: { id: true, name: true, url: true, content_tree: true }, + }), + comps: await _db.component.findMany({ + where: { + component_group: { + component_site: { some: { id_site: site_id } }, + }, + }, + select: { id: true, content_tree: true }, + }), + site: await _db.component.findFirst({ where: { id: site_id } }), + code: { + server: readDirectoryRecursively( + code.path(site_id, "server", "build") + ), + site: readDirectoryRecursively(code.path(site_id, "site", "build")), + }, + }; + + return await gzipAsync(JSON.stringify(result)); + } + return new Response("NOT FOUND", { status: 403 }); + }, +}; + +export function readDirectoryRecursively( + dirPath: string, + baseDir?: string[] +): Record { + const result: Record = {}; + + 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; +} diff --git a/app/srv/api/site-export.ts b/app/srv/api/site-export.ts index 9e498e5f..9623f67e 100644 --- a/app/srv/api/site-export.ts +++ b/app/srv/api/site-export.ts @@ -3,9 +3,8 @@ 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 { gzipSync } from "zlib"; import { buildNpm } from "../util/build-npm"; export const _ = { diff --git a/app/srv/init.ts b/app/srv/init.ts index d3aed0a9..de62a55d 100644 --- a/app/srv/init.ts +++ b/app/srv/init.ts @@ -1,3 +1,4 @@ +import { validate } from "uuid"; import { glb } from "./global"; import { server } from "./ws/sync/editor/code/server-main"; glb.npm = { page: {}, site: {} }; @@ -25,11 +26,13 @@ glb.ws_hook = { glb.server_hook = async (arg) => { const url = arg.url; - if (url.pathname.startsWith("/prod")) { + if (url.pathname.startsWith("/prod/")) { const arr = url.pathname.split("/"); const site_id = arr[2]; - return await server.http(site_id, arg); + if (arr.length >= 3 && validate(site_id)) { + return await server.http(site_id, arg); + } } if (arg.handle) return await arg.handle(arg.req); diff --git a/app/srv/ws/sync/entity/zlib.ts b/app/srv/ws/sync/entity/zlib.ts index 16e5363a..0df377a9 100644 --- a/app/srv/ws/sync/entity/zlib.ts +++ b/app/srv/ws/sync/entity/zlib.ts @@ -1,6 +1,6 @@ import { gzip, gunzip } from "zlib"; -export const gzipAsync = (bin: Uint8Array) => { +export const gzipAsync = (bin: Uint8Array | string) => { return new Promise((resolve, reject) => { gzip(bin, (err, res) => { if (err) {