Unify commercial runtime ownership across backend and frontend so platform, experience, and hospitality modules use the shared commercial source of truth. Co-authored-by: Cursor <cursoragent@cursor.com>
98 lines
3.0 KiB
JavaScript
98 lines
3.0 KiB
JavaScript
#!/usr/bin/env node
|
|
import fs from "node:fs";
|
|
import path from "node:path";
|
|
|
|
const dir = path.join("frontend", "modules", "experience", "features");
|
|
const CODE_HINT = "لاتین/عدد/_/- حداقل ۲ کاراکتر. فارسی و فاصله مجاز نیست.";
|
|
|
|
const NEED_WS = new Set([
|
|
"components",
|
|
"themes",
|
|
"layouts",
|
|
"templates",
|
|
"forms",
|
|
"surveys",
|
|
"localeProfiles",
|
|
"mediaRefs",
|
|
"localizations",
|
|
"widgetDefinitions",
|
|
"configurations",
|
|
"externalProviders",
|
|
"renderEngines",
|
|
"seoMetadata",
|
|
"sitemapShells",
|
|
"robotsShells",
|
|
"pwaManifests",
|
|
"analyticsReportDefinitions",
|
|
"publishTargets",
|
|
"publishReleases",
|
|
]);
|
|
|
|
const READ_ONLY = new Set([
|
|
"templateVersions",
|
|
"templateInstantiations",
|
|
"componentVersions",
|
|
"themeVersions",
|
|
"layoutVersions",
|
|
"siteThemeBindings",
|
|
"pageLayoutBindings",
|
|
"formSubmissions",
|
|
"surveyResponses",
|
|
"domainEdgeBindings",
|
|
"analyticsSnapshots",
|
|
"widgetInstances",
|
|
]);
|
|
|
|
for (const f of fs.readdirSync(dir)) {
|
|
if (!f.endsWith(".tsx")) continue;
|
|
const fileKey = f.replace(/\.tsx$/, "");
|
|
const p = path.join(dir, f);
|
|
let s = fs.readFileSync(p, "utf8");
|
|
if (!s.includes("createExperienceListPage")) continue;
|
|
const m = s.match(/resourceKey:\s*"([^"]+)"/);
|
|
const rk = m ? m[1] : fileKey;
|
|
|
|
if (READ_ONLY.has(rk) || READ_ONLY.has(fileKey)) {
|
|
if (!s.includes("readOnly: true")) {
|
|
const replaced = s.replace(/\n\s*createFields:\s*\[[\s\S]*?\],?\n/, "\n readOnly: true,\n");
|
|
s = replaced.includes("readOnly: true")
|
|
? replaced
|
|
: s.replace(
|
|
/api:\s*experienceApi\.[^,]+,/,
|
|
(x) =>
|
|
`${x}\n readOnly: true,\n description: "این فهرست فقط مشاهده است — ایجاد از مسیر والد.",`
|
|
);
|
|
fs.writeFileSync(p, s);
|
|
console.log("readonly", f);
|
|
}
|
|
continue;
|
|
}
|
|
|
|
if (!(NEED_WS.has(rk) || NEED_WS.has(fileKey))) continue;
|
|
if (s.includes('type: "workspace"')) {
|
|
console.log("skip-ws", f);
|
|
continue;
|
|
}
|
|
|
|
const before = s;
|
|
s = s.replace(
|
|
/createFields:\s*\[\s*\{\s*name:\s*"code",\s*label:\s*"کد",\s*required:\s*true\s*\},\s*\{\s*name:\s*"name",\s*label:\s*"نام",\s*required:\s*true\s*\},/,
|
|
`createFields: [
|
|
{ name: "workspace_id", label: "فضای کاری", type: "workspace", required: true, createOnly: true },
|
|
{ name: "code", label: "کد یکتا", required: true, placeholder: "main", hint: "${CODE_HINT}" },
|
|
{ name: "name", label: "نام", required: true },`
|
|
);
|
|
|
|
if (s === before) {
|
|
s = s.replace(
|
|
/createFields:\s*\[\s*\{\s*name:\s*"code",\s*label:\s*"کد",\s*required:\s*true\s*\},/,
|
|
`createFields: [
|
|
{ name: "workspace_id", label: "فضای کاری", type: "workspace", required: true, createOnly: true },
|
|
{ name: "code", label: "کد یکتا", required: true, placeholder: "main", hint: "${CODE_HINT}" },`
|
|
);
|
|
}
|
|
|
|
fs.writeFileSync(p, s);
|
|
console.log("ws", f, s.includes('type: "workspace"') ? "ok" : "FAIL");
|
|
}
|