123 lines
4.7 KiB
JavaScript
123 lines
4.7 KiB
JavaScript
/**
|
||
* get-site-config.js
|
||
* ------------------------------------------------------------
|
||
* プリザンターの指定サイトの構成情報(SiteSettings等)を取得し、
|
||
* ./configs/ 配下にタイムスタンプ付きJSONとして保存します。
|
||
*
|
||
* 使い方:
|
||
* node get-site-config.js
|
||
* node get-site-config.js ./config.json ← 設定ファイルを明示指定する場合
|
||
*
|
||
* 事前準備:
|
||
* 1. config.example.json を config.json にコピーし、
|
||
* BaseUrl / SiteId / ApiKey を実環境の値に書き換えてください。
|
||
* 2. Node.js 18以降(組み込みfetchを使用)
|
||
*
|
||
* 参照した公式マニュアル:
|
||
* - 開発者向け機能:API:サイト操作:サイト更新
|
||
* https://pleasanter.org/manual/api-site-update
|
||
* - 開発者向け機能:API:サイト操作:サイト設定の更新(部分追加/更新/削除)
|
||
* https://pleasanter.org/ja/manual/api-update-sitesettings
|
||
*
|
||
* 注意:
|
||
* プリザンターのバージョンにより get のレスポンス構造
|
||
* (SiteSettingsが Response.Site 配下にあるか等)が異なる場合があります。
|
||
* 初回実行時はコンソールに出力されるレスポンスのトップレベルキーを確認し、
|
||
* 想定通りの構造か確認してください。
|
||
* ------------------------------------------------------------
|
||
*/
|
||
|
||
const fs = require("fs");
|
||
const path = require("path");
|
||
const { extractSiteConfig } = require("./extract-site-config");
|
||
|
||
async function main() {
|
||
const configPath = process.argv[2] || path.join(__dirname, "config.json");
|
||
|
||
if (!fs.existsSync(configPath)) {
|
||
console.error(`[エラー] 設定ファイルが見つかりません: ${configPath}`);
|
||
console.error("config.example.json をコピーして config.json を作成してください。");
|
||
process.exit(1);
|
||
}
|
||
|
||
const config = JSON.parse(fs.readFileSync(configPath, "utf-8"));
|
||
const { BaseUrl, SiteId, ApiKey, ApiVersion } = config;
|
||
|
||
if (!BaseUrl || !SiteId || !ApiKey) {
|
||
console.error("[エラー] config.json に BaseUrl / SiteId / ApiKey を設定してください。");
|
||
process.exit(1);
|
||
}
|
||
|
||
const url = `${BaseUrl.replace(/\/+$/, "")}/api/items/${SiteId}/getsite`;
|
||
const body = {
|
||
ApiVersion: ApiVersion || "1.1",
|
||
ApiKey: ApiKey,
|
||
};
|
||
|
||
console.log(`[INFO] 取得先: ${url}`);
|
||
console.log(`[INFO] SiteId: ${SiteId}`);
|
||
|
||
let response;
|
||
try {
|
||
response = await fetch(url, {
|
||
method: "POST",
|
||
headers: { "Content-Type": "application/json" },
|
||
body: JSON.stringify(body),
|
||
});
|
||
} catch (err) {
|
||
console.error("[エラー] リクエスト送信に失敗しました:", err.message);
|
||
console.error("BaseUrlの疎通・ネットワーク設定を確認してください。");
|
||
process.exit(1);
|
||
}
|
||
|
||
const text = await response.text();
|
||
|
||
if (!response.ok) {
|
||
console.error(`[エラー] HTTP ${response.status} ${response.statusText}`);
|
||
console.error(text);
|
||
process.exit(1);
|
||
}
|
||
|
||
let json;
|
||
try {
|
||
json = JSON.parse(text);
|
||
} catch (err) {
|
||
console.error("[エラー] レスポンスがJSONとして解析できませんでした。");
|
||
console.error(text);
|
||
process.exit(1);
|
||
}
|
||
|
||
// レスポンス構造の確認用ログ(初回はここを見て構造を把握してください)
|
||
console.log("[INFO] レスポンス トップレベルキー:", Object.keys(json));
|
||
if (json.Response) {
|
||
console.log("[INFO] Response配下のキー:", Object.keys(json.Response));
|
||
}
|
||
|
||
// 保存
|
||
const outDir = path.join(__dirname, "configs");
|
||
if (!fs.existsSync(outDir)) fs.mkdirSync(outDir, { recursive: true });
|
||
|
||
const timestamp = new Date()
|
||
.toISOString()
|
||
.replace(/[:.]/g, "-");
|
||
const outFile = path.join(outDir, `site-${SiteId}_${timestamp}.json`);
|
||
|
||
fs.writeFileSync(outFile, JSON.stringify(json, null, 2), "utf-8");
|
||
|
||
// 常に「最新」ファイルも別名で保持(Claudeへのアップロード用に固定名があると便利)
|
||
const latestFile = path.join(outDir, `site-${SiteId}_latest.json`);
|
||
fs.writeFileSync(latestFile, JSON.stringify(json, null, 2), "utf-8");
|
||
|
||
console.log(`[OK] 保存しました: ${outFile}`);
|
||
console.log(`[OK] 最新版としても保存しました: ${latestFile}`);
|
||
|
||
// 取得と同時に Scripts/Styles/ServerScripts/Processes/ガイドHTML も抽出する
|
||
console.log("\n[INFO] 続けて設定の個別ファイル抽出を実行します...");
|
||
extractSiteConfig(latestFile);
|
||
|
||
console.log("\n次のステップ: latest.jsonをClaudeのチャットにアップロードして仕様書化を依頼するか、");
|
||
console.log("configs/site-{SiteId}/ 配下のファイルを直接編集・指示して修正してください。");
|
||
}
|
||
|
||
main();
|