#!/usr/bin/env node /** * منبع حقیقت: khaneghi_server/database/sql/deploy_settings_const.sql * خروجی: * - prisma/setting-templates-from-deploy.json (فقط can_edit=0 نهایی) * - src/program-settings/deploy-setting-catalog-keys.ts * - ../controlpanel_user/src/config/superAdminSettingKeys.ts */ import { readFileSync, writeFileSync } from 'fs'; import { dirname, join } from 'path'; import { fileURLToPath } from 'url'; const __dirname = dirname(fileURLToPath(import.meta.url)); const root = join(__dirname, '..'); const sqlPath = join( root, '../khaneghi_server/database/sql/deploy_settings_const.sql', ); const sql = readFileSync(sqlPath, 'utf8'); /** @type {Map} */ const rows = new Map(); function unquote(s) { return String(s ?? '') .trim() .replace(/^'/, '') .replace(/'$/, '') .replace(/\\'/g, "'") .replace(/\\n/g, '\n'); } // INSERT … SELECT 'key', 'value', … for (const m of sql.matchAll( /SELECT\s+'([^']+)',\s+'((?:\\'|[^'])*)',\s+'((?:\\'|[^'])*)',\s+(\d+),\s+(\d+)(?:,\s+(NULL|'(?:\\'|[^'])*'))(?:,\s+'((?:\\'|[^'])*)')?/g, )) { const key = m[1]; const value = unquote(`'${m[2]}'`); const title_fa = unquote(`'${m[3]}'`); const can_edit = Number(m[4]); const is_active = Number(m[5]); let description = ''; if (m[6] && m[6] !== 'NULL') description = unquote(m[6]); const type = m[7] ? unquote(`'${m[7]}'`) : ''; rows.set(key, { key, value, title_fa, can_edit, is_active, description, type }); } function applyCanEdit(block, value) { const keys = [...block.matchAll(/'([^']+)'/g)].map((x) => x[1]); for (const key of keys) { const row = rows.get(key); if (row) row.can_edit = value; } } // UPDATE can_edit = 0/1 batches for (const m of sql.matchAll( /UPDATE\s+`settings`\s+SET\s+`can_edit`\s*=\s*(\d)(?:,\s*`[^`]+`\s*=[^W]+)?\s+WHERE\s+`key`\s+IN\s*\(([\s\S]*?)\)\s*;/g, )) { applyCanEdit(m[2], Number(m[1])); } for (const m of sql.matchAll( /UPDATE\s+`settings`\s+SET\s+`can_edit`\s*=\s*(\d)\s+WHERE\s+`key`\s*=\s*'([^']+)'/g, )) { const row = rows.get(m[2]); if (row) row.can_edit = Number(m[1]); } // zarin_* wildcard if (/UPDATE\s+`settings`\s+SET\s+`can_edit`\s*=\s*0,\s*`is_active`\s*=\s*1\s+WHERE\s+`key`\s+LIKE\s+'zarin_%'/.test(sql)) { for (const [key, row] of rows) { if (key.startsWith('zarin_')) row.can_edit = 0; } } // type-only UPDATE batches — enrich type when present for (const m of sql.matchAll( /UPDATE\s+`settings`\s+SET\s+`type`\s*=\s*'([^']+)'\s+WHERE\s+`key`\s+IN\s*\(([\s\S]*?)\)\s*;/g, )) { const type = m[1]; for (const key of [...m[2].matchAll(/'([^']+)'/g)].map((x) => x[1])) { const row = rows.get(key); if (row && type) row.type = type; } } const systemRows = [...rows.values()] .filter((r) => r.can_edit === 0) .sort((a, b) => a.key.localeCompare(b.key)); const editableRows = [...rows.values()] .filter((r) => r.can_edit === 1) .sort((a, b) => a.key.localeCompare(b.key)); const jsonOut = systemRows.map((r) => ({ key: r.key, value: r.value ?? '', title_fa: r.title_fa ?? r.key, can_edit: 0, is_active: r.is_active ?? 1, description: r.description ?? '', type: r.type ?? '', })); const tsKeys = `/** * کلیدهای can_edit=0 در deploy_settings_const.sql — فقط همین‌ها در قالب سوپرادمین. * تولید خودکار: node scripts/sync-superadmin-setting-template.mjs */ export const DEPLOY_SETTING_CATALOG_KEYS = new Set([ ${systemRows.map((r) => ` ${JSON.stringify(r.key)},`).join('\n')} ]); /** کلیدهای can_edit=1 — نباید در قالب/جدول settings سوپرادمین باشند */ export const DEPLOY_SETTING_EDITABLE_KEYS = new Set([ ${editableRows.map((r) => ` ${JSON.stringify(r.key)},`).join('\n')} ]); `; writeFileSync(join(root, 'prisma/setting-templates-from-deploy.json'), `${JSON.stringify(jsonOut, null, 2)}\n`); writeFileSync(join(root, 'src/program-settings/deploy-setting-catalog-keys.ts'), `${tsKeys}\n`); const userTs = `/** * کلیدهای تنظیمات سوپرادمین — هم‌تراز deploy_settings_const.sql * تولید خودکار: controlpanel_server/scripts/sync-superadmin-setting-template.mjs */ export const SUPERADMIN_SYSTEM_SETTING_KEYS = new Set([ ${systemRows.map((r) => ` ${JSON.stringify(r.key)},`).join('\n')} ]); export const SUPERADMIN_EDITABLE_SETTING_KEYS = new Set([ ${editableRows.map((r) => ` ${JSON.stringify(r.key)},`).join('\n')} ]); export function isSuperAdminSystemSettingKey(key?: string | null): boolean { const k = String(key || '').trim(); if (!k) return false; if (SUPERADMIN_EDITABLE_SETTING_KEYS.has(k)) return false; return SUPERADMIN_SYSTEM_SETTING_KEYS.has(k); } `; writeFileSync(join(root, '../controlpanel_user/src/config/superAdminSettingKeys.ts'), `${userTs}\n`); console.log(`system keys (can_edit=0): ${systemRows.length}`); console.log(`editable keys (can_edit=1): ${editableRows.length}`);