UNPKG

@opengis/fastify-table

Version:

core-plugins

208 lines (207 loc) 8.6 kB
import fp from "fastify-plugin"; import path from "node:path"; import { fileURLToPath } from "node:url"; import proxy from "@fastify/http-proxy"; import addTemplateDir from "./server/plugins/table/funcs/addTemplateDir.js"; const filename = fileURLToPath(import.meta.url); const cwd = path.dirname(filename); // core templates && cls config.templates?.forEach((el) => addTemplateDir(el)); addTemplateDir(path.join(cwd, "module/core")); import config from "./config.js"; import { preForm, afterInsert, afterTable, afterTemplate, afterUpdate, preTemplate, onReady, onListen1, onListen2, } from "./functions.js"; import addHook from "./server/plugins/hook/addHook.js"; const { maxFileSize = 512 } = config; const { name: execName } = path.parse(process.argv0); const routes = []; const policyCls = { public: "Public", // old policy support user: "User", // old policy support site: "Public", // old policy support L0: "Public", L1: "User", L2: "User", L3: "User", }; // helpers // import helperPlugin from './server/helpers/index.js'; // plugins import cronPlugin from "./server/plugins/cron/index.js"; import pgPlugin from "./server/plugins/pg/index.js"; import sqlitePlugin from "./server/plugins/sqlite/index.js"; import policyPlugin from "./server/plugins/policy/index.js"; import metricPlugin from "./server/plugins/metric/index.js"; import redisPlugin from "./server/plugins/redis/index.js"; import loggerPlugin from "./server/plugins/logger/index.js"; import authPlugin from "./server/plugins/auth/index.js"; // utils import execMigrations from "./server/plugins/migration/exec.migrations.js"; import pgClients from "./server/plugins/pg/pgClients.js"; // routes import cronRoutes from "./server/routes/cron/index.js"; import crudRoutes from "./server/routes/crud/index.js"; import loggerRoutes from "./server/routes/logger/index.js"; import propertiesRoutes from "./server/routes/properties/index.js"; import tableRoutes from "./server/routes/table/index.js"; import utilRoutes from "./server/routes/util/index.js"; import accessRoutes from "./server/routes/access/index.js"; import dblistRoutes from "./server/routes/dblist/index.js"; import menuRoutes from "./server/routes/menu/index.js"; import templatesRoutes from "./server/routes/templates/index.js"; import widgetRoutes from "./server/routes/widget/index.js"; import authRoutes from "./server/routes/auth/index.js"; import fileRoutes from "./server/routes/file/index.js"; import uploadChunkRoutes from "./server/routes/upload/index.js"; import grpcRoutes from "./server/routes/grpc/index.js"; import notificationsRoutes from "./server/routes/notifications/index.js"; import userClsRoutes from "./server/routes/usercls/index.js"; addHook("preForm", preForm); addHook("afterTable", afterTable); addHook("preTemplate", preTemplate); addHook("afterTemplate", afterTemplate); addHook("afterUpdate", afterUpdate); addHook("afterInsert", afterInsert); function plugin(fastify) { const opt = { prefix: "/api" }; if (config.disableCors) { fastify.addHook("onSend", async (request, reply) => { reply.header("Access-Control-Allow-Origin", "*"); }); } if (!fastify.hasRoute({ method: "GET", url: "/api/list" })) { fastify.get(`${opt.prefix}/list`, { config: { role: "admin" } }, ({ query }) => { const { package: packageName, subdir } = query; if (packageName) { return { rows: routes.filter((r) => r.package === packageName) }; } if (subdir) { return { rows: routes.filter((r) => r.subdir === subdir) }; } return { rows: routes }; }); } fastify.addHook("onRoute", (r) => { if (r.method === "HEAD") return; const method = Array.isArray(r.method) ? "ALL" : r.method; const query = r.schema?.querystring ? Object.keys(r.schema?.querystring?.properties || {}).reduce((acc, curr) => ({ ...acc, [curr]: r.schema?.querystring?.properties?.[curr]?.type, }), {}) : undefined; r.config = r.config || {}; r.config.package = r.config.package || "fastify-table"; routes.push({ method, route: r.url, subdir: r.config?.subdir, package: r.config?.package, description: r.config?.description, query, roles: r.config?.role?.split?.("|"), policy: (Array.isArray(r.config?.policy) ? r.config?.policy : r.config?.policy?.split?.(","))?.map?.((name) => policyCls[name] || name), }); }); fastify.addHook("onListen", onListen1); fastify.addHook("onListen", onListen2); fastify.addHook("onReady", onReady); // core migrations (second argument for core only) execMigrations(path.join(cwd, "server/migrations"), pgClients.client, true).catch((err) => console.warn(err.toString())); // plugins / utils / funcs policyPlugin(fastify); authPlugin(fastify); // fastify-auth api + hooks integrated to core metricPlugin(); redisPlugin(fastify); pgPlugin(fastify); sqlitePlugin(fastify); cronPlugin(); loggerPlugin(fastify); if (config.rateLimit !== false) { fastify.register(import("@fastify/rate-limit"), { max: parseInt(config.rateLimit?.max || 100), timeWindow: config.rateLimit?.timeWindow || 60000, hook: "preHandler", global: true, keyGenerator: (req) => `${req.ip}-${req.raw.url.split("?")[0]}`, }); } else { console.log("⚠️ rate limit is disabled"); } // add multipart parser before any route registration fastify.register(import("@fastify/multipart"), { limits: { fileSize: maxFileSize * 1024 * 1024, }, }); if (config.dblist) { fastify.register(dblistRoutes, opt); } // routes / api fastify.register(cronRoutes, opt); fastify.register(crudRoutes, opt); fastify.register(loggerRoutes); fastify.register(propertiesRoutes, opt); fastify.register(tableRoutes, opt); fastify.register(utilRoutes, opt); fastify.register(accessRoutes, opt); fastify.register(widgetRoutes, opt); fastify.register(menuRoutes, opt); fastify.register(templatesRoutes, opt); fastify.register(authRoutes); // from fastify-auth // from fastify-file fastify.register(fileRoutes); fastify.register(uploadChunkRoutes); fastify.register(grpcRoutes, opt); // from admin fastify.register(notificationsRoutes, opt); fastify.register(userClsRoutes, opt); config.proxy?.forEach?.((el) => { if (execName === "bun") { fastify.all(`${el.source}/*`, async (req, reply) => { const url = el.target.replace(/\/$/, "") + req.raw.url.replace(new RegExp(`^${el.source}`), ""); const res = await fetch(url, { method: req.method, headers: { // ...req.headers, uid: req.user?.uid, ...(el.headers || {}), }, body: ["PUT", "POST"].includes(req.method) ? req.raw : undefined, }); reply.headers(Object.fromEntries(res.headers)); reply.status(res.status); if (res.headers.get("content-type")?.startsWith?.("text/")) { const resp = await res.text(); // reply.send(resp); return resp; } if (res.headers.get("content-type")?.includes?.("/json")) { const resp = await res.json(); // reply.send(resp); return resp; } const blob = await res.blob(); const arrayBuffer = await blob.arrayBuffer(); const fileBuffer = Buffer.from(arrayBuffer); return fileBuffer; }); } else { fastify.register(proxy, { upstream: el.target, prefix: el.source, http2: false, preHandler: async (req) => { req.headers.uid = req.session?.passport?.user?.uid; Object.keys(el.headers || {})?.forEach((item) => (req.headers[item] = el.headers[item])); }, }); } }); } export default fp(plugin);