140 lines
6.6 KiB
JavaScript
140 lines
6.6 KiB
JavaScript
/**
|
||
* build-desired-config.js
|
||
* ------------------------------------------------------------
|
||
* extract-site-config.js で分割した configs/site-{SiteId}/ 配下のファイル
|
||
* (scripts/*.js, styles/*.css, serverscripts/*.js, processes.json)を
|
||
* manifest.json を手がかりに再構成し、apply-site-config.js が読み込む
|
||
* desired_config.json を生成します。
|
||
*
|
||
* ★★★ このスクリプトもAPIへは一切送信しません(ファイル生成のみ)。★★★
|
||
* 反映は既存の運用どおり、
|
||
* 1. node apply-site-config.js でドライラン確認(差分・送信Body・curl表示)
|
||
* 2. 内容を確認し、問題なければ表示されたcurlコマンドを手動実行
|
||
* の流れに乗せてください。
|
||
*
|
||
* 使い方:
|
||
* node build-desired-config.js site-214812
|
||
* (フォルダ名は "site-{SiteId}_{サイト名}" 形式だが、"site-{SiteId}" だけの
|
||
* 前方一致指定でも configs/ 配下から自動的に該当フォルダを探して解決する)
|
||
* node build-desired-config.js ./configs/site-214812_物件基本情報
|
||
*
|
||
* 出力: desired_config.json(このスクリプトと同じ階層。既存ファイルは上書き)
|
||
*
|
||
* 対応範囲:
|
||
* Scripts / Styles / ServerScripts / Processes
|
||
* → Mode:"partial"(updatesitesettings)で反映可能なため、そのまま組み込みます。
|
||
* Html(GridGuide等のガイド)
|
||
* → SiteSettingsではなくサイトデータ直下の項目のため、
|
||
* 部分更新(updatesitesettings)には含められません。
|
||
* 反映したい場合は Mode:"full"(updatesite)用の別JSONを用意し、
|
||
* Title/ReferenceType等の必須項目とあわせて指定してください。
|
||
* このスクリプトはhtml/配下に抽出物がある場合、警告のみ表示します。
|
||
* ------------------------------------------------------------
|
||
*/
|
||
|
||
const fs = require("fs");
|
||
const path = require("path");
|
||
|
||
function readJson(p) {
|
||
return JSON.parse(fs.readFileSync(p, "utf-8"));
|
||
}
|
||
|
||
// フォルダ名は "site-{SiteId}_{サイト名}" 形式。"site-{SiteId}" のみの指定でも
|
||
// configs/ 配下から前方一致で該当フォルダを探して解決する。
|
||
// 新形式(サイト名付き)を優先し、裸の "site-{SiteId}" 完全一致(リネーム前の古い抽出結果の可能性)は
|
||
// 他に候補が無い場合のみ後方互換フォールバックとして使う。
|
||
function resolveSiteDir(baseDir, arg) {
|
||
const configsDir = path.join(baseDir, "configs");
|
||
const direct = path.isAbsolute(arg) ? arg : path.join(configsDir, path.basename(arg));
|
||
const baseName = path.basename(arg);
|
||
|
||
const candidates = fs.existsSync(configsDir)
|
||
? fs.readdirSync(configsDir).filter((name) => {
|
||
const full = path.join(configsDir, name);
|
||
return (
|
||
fs.statSync(full).isDirectory() && (name === baseName || name.startsWith(`${baseName}_`))
|
||
);
|
||
})
|
||
: [];
|
||
|
||
const suffixed = candidates.filter((name) => name !== baseName);
|
||
if (suffixed.length === 1) return path.join(configsDir, suffixed[0]);
|
||
if (suffixed.length > 1) {
|
||
console.error(`[エラー] "${baseName}" に一致するフォルダが複数見つかりました: ${suffixed.join(", ")}`);
|
||
console.error("フォルダ名をフルで指定してください。");
|
||
process.exit(1);
|
||
}
|
||
|
||
if (candidates.includes(baseName)) return path.join(configsDir, baseName);
|
||
if (fs.existsSync(direct) && fs.statSync(direct).isDirectory()) return direct;
|
||
|
||
console.error(`[エラー] フォルダが見つかりません: ${direct}`);
|
||
console.error("先に node extract-site-config.js(またはnode get-site-config.js)を実行してください。");
|
||
process.exit(1);
|
||
}
|
||
|
||
function rebuildList(manifestEntries, dir, bodyKey = "Body") {
|
||
return (manifestEntries || []).map((entry) => {
|
||
const { File, ...meta } = entry;
|
||
const filePath = path.join(dir, File);
|
||
if (!fs.existsSync(filePath)) {
|
||
console.error(`[エラー] manifest.jsonに記載のファイルが見つかりません: ${filePath}`);
|
||
process.exit(1);
|
||
}
|
||
const body = fs.readFileSync(filePath, "utf-8");
|
||
return { ...meta, [bodyKey]: body };
|
||
});
|
||
}
|
||
|
||
function main() {
|
||
const baseDir = __dirname;
|
||
const arg = process.argv[2];
|
||
if (!arg) {
|
||
console.error("[エラー] 対象フォルダを指定してください(例: node build-desired-config.js site-214812)");
|
||
process.exit(1);
|
||
}
|
||
const siteDir = resolveSiteDir(baseDir, arg);
|
||
|
||
const manifestPath = path.join(siteDir, "manifest.json");
|
||
if (!fs.existsSync(manifestPath)) {
|
||
console.error(`[エラー] manifest.jsonが見つかりません: ${manifestPath}`);
|
||
console.error("先に node extract-site-config.js を実行してください。");
|
||
process.exit(1);
|
||
}
|
||
const manifest = readJson(manifestPath);
|
||
|
||
const siteSettings = {};
|
||
|
||
siteSettings.Scripts = rebuildList(manifest.Scripts, path.join(siteDir, "scripts"));
|
||
siteSettings.Styles = rebuildList(manifest.Styles, path.join(siteDir, "styles"));
|
||
siteSettings.ServerScripts = rebuildList(manifest.ServerScripts, path.join(siteDir, "serverscripts"));
|
||
|
||
const processesPath = path.join(siteDir, manifest.ProcessesFile || "processes.json");
|
||
siteSettings.Processes = fs.existsSync(processesPath) ? readJson(processesPath) : [];
|
||
|
||
const desired = {
|
||
Mode: "partial",
|
||
SiteId: manifest.SiteId,
|
||
SiteSettings: siteSettings,
|
||
};
|
||
|
||
const outPath = path.join(baseDir, "desired_config.json");
|
||
fs.writeFileSync(outPath, JSON.stringify(desired, null, 2), "utf-8");
|
||
|
||
console.log(`[OK] 生成しました: ${outPath}`);
|
||
console.log(` Scripts : ${siteSettings.Scripts.length}件`);
|
||
console.log(` Styles : ${siteSettings.Styles.length}件`);
|
||
console.log(` ServerScripts : ${siteSettings.ServerScripts.length}件`);
|
||
console.log(` Processes : ${siteSettings.Processes.length}件`);
|
||
|
||
if (manifest.Html && manifest.Html.length > 0) {
|
||
console.log("\n[注意] html/ 配下のガイドHTMLは、この desired_config.json には含まれていません。");
|
||
console.log(" GridGuide等はSiteSettingsではなくサイト直下の項目のため、部分更新(updatesitesettings)では送れません。");
|
||
console.log(' 反映するには Mode:"full"(updatesite)用の別JSONを用意し、Title等の必須項目とあわせて指定してください。');
|
||
}
|
||
|
||
console.log("\n次のステップ: node apply-site-config.js でドライラン確認 → 内容確認の上、表示されたcurlコマンドを手動実行してください。");
|
||
}
|
||
|
||
main();
|