ken_nogi/ClaudePleasanter/★マスターシート/.claude/js/apply-desired-config-full.js
Kenichiro NOGI ed33892f08 chore: 作業中の変更を整理しコミット(複数プロジェクト分)
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-02 11:09:50 +09:00

128 lines
5.5 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/**
* apply-desired-config-full.js
* ------------------------------------------------------------
* この環境では updatesitesettings部分更新がHTTP 200を返しても実際には
* 反映されないことを確認済みのためREADME.md「注意事項」参照
* Scripts/Styles/ServerScripts/Processesの反映には常にこちらを使う。
*
* build-desired-config.js が生成した desired_config.json の
* Scripts/Styles/ServerScripts/Processes を、現在のサイト全体getsite
* 上書きマージし、updatesite全体更新で送信する。
* Columns/GridColumns/Permissions等、それ以外のSiteSettings・Title等は
* 現状のまま一切変更しない。
*
* 使い方:
* node build-desired-config.js site-{SiteId}_{サイト名} … 先にこちらを実行
* node apply-desired-config-full.js … 差分表示のみ(送信なし)
* node apply-desired-config-full.js --execute … 上記に加えて実際に送信する
* ------------------------------------------------------------
*/
const fs = require("fs");
const path = require("path");
const { findSiteDir, newModifyDir, latestModifyDir } = require("./site-paths");
const baseDir = path.join(__dirname, "..", "..");
const execute = process.argv.includes("--execute");
function loadJson(p) {
return JSON.parse(fs.readFileSync(p, "utf-8"));
}
function maskApiKey(key) {
if (!key) return key;
return key.length > 8 ? key.slice(0, 4) + "****" + key.slice(-4) : "****";
}
function timestamp() {
return new Date().toISOString().replace(/[:.]/g, "-");
}
function diffList(curList, desList, key) {
(curList || []).forEach((c) => {
const d = (desList || []).find((x) => x.Id === c.Id);
const same = d && JSON.stringify(d) === JSON.stringify(c);
console.log(` ${key} Id:${c.Id} (${c.Title || c.Name || ""}) -> 変更${!same}`);
});
}
const config = loadJson(path.join(baseDir, "config.json"));
const desired = loadJson(path.join(baseDir, "desired_config.json"));
const SITE_ID = desired.SiteId;
const siteDir = findSiteDir(path.join(baseDir, "configs"), SITE_ID);
(async () => {
console.log("[INFO] 現在のサイト情報を取得しています...");
const getUrl = `${config.BaseUrl.replace(/\/+$/, "")}/api/items/${SITE_ID}/getsite`;
const getRes = await fetch(getUrl, {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ ApiVersion: config.ApiVersion || "1.1", ApiKey: config.ApiKey }),
});
const getJson = await getRes.json();
if (getJson.StatusCode !== 200) {
console.error("[エラー] getsiteに失敗しました:", JSON.stringify(getJson).slice(0, 500));
process.exit(1);
}
const data = getJson.Response.Data;
console.log(`[OK] 取得しました現在のVer: ${data.Ver}, UpdatedTime: ${data.UpdatedTime}`);
const siteSettings = JSON.parse(JSON.stringify(data.SiteSettings));
console.log("========================================");
console.log(` Scripts/Styles/ServerScripts/Processes 差し替えupdatesite全体更新${execute ? "(実行)" : "(プレビューのみ)"}`);
console.log("========================================");
console.log("--- Scripts ---");
diffList(siteSettings.Scripts, desired.SiteSettings.Scripts, "Script");
console.log("--- Styles ---");
diffList(siteSettings.Styles, desired.SiteSettings.Styles, "Style");
console.log("--- ServerScripts ---");
diffList(siteSettings.ServerScripts, desired.SiteSettings.ServerScripts, "ServerScript");
console.log("他のSiteSettingsColumns/GridColumns等・Permissions・Title等は一切変更しません。");
siteSettings.Scripts = desired.SiteSettings.Scripts;
siteSettings.Styles = desired.SiteSettings.Styles;
siteSettings.ServerScripts = desired.SiteSettings.ServerScripts;
siteSettings.Processes = desired.SiteSettings.Processes;
const body = {
ApiVersion: config.ApiVersion || "1.1",
ApiKey: config.ApiKey,
SiteId: SITE_ID,
Title: data.Title,
ReferenceType: data.ReferenceType,
ParentId: data.ParentId,
InheritPermission: data.InheritPermission,
Permissions: data.Permissions,
SiteSettings: siteSettings,
};
const modifyDir = latestModifyDir(siteDir) || newModifyDir(siteDir, "desired-config-full-update");
const ts = timestamp();
const maskedBody = { ...body, ApiKey: maskApiKey(body.ApiKey) };
const previewPath = path.join(modifyDir, `site-${SITE_ID}_full_update_preview_${ts}.json`);
fs.writeFileSync(previewPath, JSON.stringify(maskedBody, null, 2), "utf-8");
console.log(`\n[OK] 送信予定内容を保存しました: ${previewPath}`);
if (!execute) {
console.log("\n[注意] --execute が指定されていないため、送信は行っていません。");
console.log("内容を確認の上、問題なければ次を実行してください: node apply-desired-config-full.js --execute");
process.exit(0);
}
console.log("\n実際に送信しますupdatesite...");
const url = `${config.BaseUrl.replace(/\/+$/, "")}/api/items/${SITE_ID}/updatesite`;
const res = await fetch(url, {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify(body),
});
const text = await res.text();
const resultOutPath = path.join(modifyDir, `site-${SITE_ID}_full_update_result_${ts}.json`);
fs.writeFileSync(resultOutPath, text, "utf-8");
console.log(`HTTP ${res.status} ${res.statusText}`);
console.log(`[OK] 応答を保存しました: ${resultOutPath}`);
console.log(text);
})();