144 lines
4.4 KiB
JavaScript
144 lines
4.4 KiB
JavaScript
#!/usr/bin/env node
|
|
// One-shot: FASE 3 helper, safe to delete after merge.
|
|
//
|
|
// Moves existing i18n mirror docs from `docs/i18n/<lang>/docs/X.md` into the
|
|
// matching subfolder `docs/i18n/<lang>/docs/<sub>/X.md`, mirroring the new
|
|
// docs/ layout. Uses `git mv` to preserve history.
|
|
//
|
|
// Usage:
|
|
// node scripts/docs/move-i18n-mirrors.mjs [--dry]
|
|
//
|
|
// Notes:
|
|
// - Skips files that don't appear in DOC_TO_SUBFOLDER (e.g., the legacy
|
|
// `cloudflare-zero-trust-guide.md` or `features/` subfolder — those will be
|
|
// handled in FASE 5 when translations are regenerated).
|
|
// - Idempotent: if the target already lives under a subfolder, the entry is
|
|
// skipped.
|
|
|
|
import fs from "node:fs";
|
|
import path from "node:path";
|
|
import { fileURLToPath } from "node:url";
|
|
import { execFileSync } from "node:child_process";
|
|
|
|
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
|
const ROOT = path.resolve(__dirname, "..", "..");
|
|
const I18N_DIR = path.join(ROOT, "docs", "i18n");
|
|
|
|
const DRY = process.argv.includes("--dry");
|
|
|
|
const DOC_TO_SUBFOLDER = {
|
|
// architecture
|
|
"ARCHITECTURE.md": "architecture",
|
|
"CODEBASE_DOCUMENTATION.md": "architecture",
|
|
"REPOSITORY_MAP.md": "architecture",
|
|
"AUTHZ_GUIDE.md": "architecture",
|
|
"RESILIENCE_GUIDE.md": "architecture",
|
|
// guides
|
|
"SETUP_GUIDE.md": "guides",
|
|
"USER_GUIDE.md": "guides",
|
|
"DOCKER_GUIDE.md": "guides",
|
|
"ELECTRON_GUIDE.md": "guides",
|
|
"TERMUX_GUIDE.md": "guides",
|
|
"PWA_GUIDE.md": "guides",
|
|
"TROUBLESHOOTING.md": "guides",
|
|
"UNINSTALL.md": "guides",
|
|
"I18N.md": "guides",
|
|
"FEATURES.md": "guides",
|
|
// reference
|
|
"API_REFERENCE.md": "reference",
|
|
"PROVIDER_REFERENCE.md": "reference",
|
|
"openapi.yaml": "reference",
|
|
"ENVIRONMENT.md": "reference",
|
|
"CLI-TOOLS.md": "reference",
|
|
"FREE_TIERS.md": "reference",
|
|
// frameworks
|
|
"MCP-SERVER.md": "frameworks",
|
|
"A2A-SERVER.md": "frameworks",
|
|
"AGENT_PROTOCOLS_GUIDE.md": "frameworks",
|
|
"CLOUD_AGENT.md": "frameworks",
|
|
"SKILLS.md": "frameworks",
|
|
"MEMORY.md": "frameworks",
|
|
"WEBHOOKS.md": "frameworks",
|
|
"EVALS.md": "frameworks",
|
|
// routing
|
|
"AUTO-COMBO.md": "routing",
|
|
"REASONING_REPLAY.md": "routing",
|
|
// security
|
|
"GUARDRAILS.md": "security",
|
|
"COMPLIANCE.md": "security",
|
|
"STEALTH_GUIDE.md": "security",
|
|
// compression
|
|
"COMPRESSION_GUIDE.md": "compression",
|
|
"COMPRESSION_ENGINES.md": "compression",
|
|
"COMPRESSION_RULES_FORMAT.md": "compression",
|
|
"COMPRESSION_LANGUAGE_PACKS.md": "compression",
|
|
"RTK_COMPRESSION.md": "compression",
|
|
// ops
|
|
"RELEASE_CHECKLIST.md": "ops",
|
|
"COVERAGE_PLAN.md": "ops",
|
|
"FLY_IO_DEPLOYMENT_GUIDE.md": "ops",
|
|
"VM_DEPLOYMENT_GUIDE.md": "ops",
|
|
"PROXY_GUIDE.md": "ops",
|
|
"TUNNELS_GUIDE.md": "ops",
|
|
};
|
|
|
|
let moved = 0;
|
|
let skipped = 0;
|
|
const seenLocales = [];
|
|
|
|
for (const locale of fs.readdirSync(I18N_DIR)) {
|
|
const localeDir = path.join(I18N_DIR, locale);
|
|
const stat = fs.statSync(localeDir);
|
|
if (!stat.isDirectory()) continue;
|
|
const docsDir = path.join(localeDir, "docs");
|
|
if (!fs.existsSync(docsDir)) continue;
|
|
seenLocales.push(locale);
|
|
|
|
for (const fname of fs.readdirSync(docsDir)) {
|
|
const sub = DOC_TO_SUBFOLDER[fname];
|
|
if (!sub) continue; // not in our mapping (e.g. features/, cloudflare-zero-trust-guide.md)
|
|
|
|
const src = path.join(docsDir, fname);
|
|
if (!fs.statSync(src).isFile()) continue;
|
|
|
|
const subDir = path.join(docsDir, sub);
|
|
const dst = path.join(subDir, fname);
|
|
|
|
if (fs.existsSync(dst)) {
|
|
skipped++;
|
|
continue;
|
|
}
|
|
|
|
if (DRY) {
|
|
console.log(`would move: ${path.relative(ROOT, src)} -> ${path.relative(ROOT, dst)}`);
|
|
moved++;
|
|
continue;
|
|
}
|
|
|
|
if (!fs.existsSync(subDir)) fs.mkdirSync(subDir, { recursive: true });
|
|
const relSrc = path.relative(ROOT, src);
|
|
const relDst = path.relative(ROOT, dst);
|
|
try {
|
|
execFileSync("git", ["mv", "-k", "--", relSrc, relDst], {
|
|
cwd: ROOT,
|
|
stdio: "pipe",
|
|
});
|
|
moved++;
|
|
} catch {
|
|
// fallback: copy + delete; emulate `|| true` for the rm by ignoring its failure
|
|
fs.renameSync(src, dst);
|
|
try {
|
|
execFileSync("git", ["rm", "--cached", "--", relSrc], { cwd: ROOT, stdio: "pipe" });
|
|
} catch {
|
|
// file may not be tracked yet — safe to ignore
|
|
}
|
|
execFileSync("git", ["add", "--", relDst], { cwd: ROOT, stdio: "pipe" });
|
|
moved++;
|
|
}
|
|
}
|
|
}
|
|
|
|
console.log(
|
|
`[i18n-mirrors] locales=${seenLocales.length} moved=${moved} skipped=${skipped}${DRY ? " (dry-run)" : ""}`
|
|
);
|