Files
meshkee/scripts/generate-sitemap-config.mjs
T
Alireza HassaniandCursor b0ba7b1de8 Add instruction list and detail pages with header category menu.
Fetch tutorials from the Meshkee API with category filtering, matching the portfolio pattern and exposing آموزش‌ها in the main navigation.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-01 11:51:19 +03:30

112 lines
3.2 KiB
JavaScript

/**
* Scans app page routes and writes src/lib/sitemap-config.generated.json
* for GET /meshkee/sitemap-config.json (Meshkee sitemap sync).
*/
import fs from "node:fs";
import path from "node:path";
import { fileURLToPath } from "node:url";
const root = path.resolve(path.dirname(fileURLToPath(import.meta.url)), "..");
const appDir = path.join(root, "src", "app");
const outFile = path.join(root, "src", "lib", "sitemap-config.generated.json");
const EXCLUDE_SEGMENTS = new Set([
"api",
"meshkee",
"admin",
"auth",
"login",
"checkout",
"cart",
"account",
]);
const PRIORITY = {
"/": { changefreq: "weekly", priority: 1.0 },
"/cms-website": { changefreq: "monthly", priority: 0.9 },
"/website": { changefreq: "monthly", priority: 0.9 },
"/website-qom": { changefreq: "monthly", priority: 0.9 },
"/seo": { changefreq: "monthly", priority: 0.8 },
"/dedicated-application": { changefreq: "monthly", priority: 0.8 },
"/meshkee-cms": { changefreq: "monthly", priority: 0.8 },
"/graphic-designer": { changefreq: "monthly", priority: 0.7 },
"/portfolio": { changefreq: "weekly", priority: 0.8 },
"/instruction": { changefreq: "weekly", priority: 0.8 },
"/blog": { changefreq: "weekly", priority: 0.8 },
};
function websiteDomain() {
const fromEnv =
process.env.NEXT_PUBLIC_WEBSITE_DOMAIN ||
process.env.WEBSITE_DOMAIN ||
process.env.NEXT_PUBLIC_MESHKEE_DOMAIN ||
process.env.NEXT_PUBLIC_SITE_URL;
if (fromEnv) {
return fromEnv.replace(/^https?:\/\//, "").replace(/\/$/, "");
}
return "www.meshkee.com";
}
function walkPages(dir, segments = []) {
/** @type {string[]} */
const pages = [];
if (!fs.existsSync(dir)) return pages;
for (const entry of fs.readdirSync(dir, { withFileTypes: true })) {
if (entry.name.startsWith(".") || entry.name === "node_modules") continue;
const full = path.join(dir, entry.name);
if (entry.isDirectory()) {
if (EXCLUDE_SEGMENTS.has(entry.name)) continue;
if (/^\[.+\]$/.test(entry.name) || /^\(.+\)$/.test(entry.name)) {
if (/^\(.+\)$/.test(entry.name)) {
pages.push(...walkPages(full, segments));
}
continue;
}
pages.push(...walkPages(full, [...segments, entry.name]));
continue;
}
if (
entry.name === "page.tsx" ||
entry.name === "page.ts" ||
entry.name === "page.jsx" ||
entry.name === "page.js"
) {
const routePath = segments.length ? `/${segments.join("/")}` : "/";
pages.push(routePath);
}
}
return pages;
}
function main() {
const paths = [...new Set(walkPages(appDir))].sort((a, b) => {
if (a === "/") return -1;
if (b === "/") return 1;
return a.localeCompare(b);
});
const staticPages = paths.map((routePath) => {
const meta = PRIORITY[routePath] ?? { priority: 0.5 };
return { path: routePath, ...meta };
});
const config = {
baseUrl: `https://${websiteDomain()}`,
staticPages,
};
fs.mkdirSync(path.dirname(outFile), { recursive: true });
fs.writeFileSync(outFile, `${JSON.stringify(config, null, 2)}\n`, "utf8");
console.log(
`Wrote ${path.relative(root, outFile)} (${staticPages.length} static pages)`,
);
}
main();