ken_nogi/ClaudePleasanter/IC(東京)【引継依頼】/.claude/js/site-paths.js
Kenichiro NOGI ed33892f08 chore: 作業中の変更を整理しコミット(複数プロジェクト分)
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-02 11:09:50 +09:00

106 lines
3.8 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.

/**
* site-paths.js
* ------------------------------------------------------------
* configs/ 配下のフォルダ構成を一箇所で管理する共有ヘルパー。
*
* 構成:
* configs/
* master/ … ユーザー/組織/グループのマスターデータget-master-data.js
* site-{SiteId}_{サイト名}/
* sitesettings/ … getsiteの生JSONsite-{SiteId}_latest.json / _{timestamp}.json
* scripts/ styles/ serverscripts/ html/ processes.json / manifest.json
* … extract-site-config.js による分割済みファイル(従来通り)
* docs/ … 仕様書(.md)や改善要望プラン等、sitesettings以外の関連ドキュメント
* modify/{request}/ … 修正依頼ごとに新規作成。変更前後のconfigファイルや差分・結果を保管
* ------------------------------------------------------------
*/
const fs = require("fs");
const path = require("path");
function sanitize(name) {
return (
String(name || "untitled")
.replace(/[\\/:*?"<>|]/g, "_")
.trim()
.slice(0, 60) || "untitled"
);
}
function ensureDir(dir) {
if (!fs.existsSync(dir)) fs.mkdirSync(dir, { recursive: true });
return dir;
}
// configs/ 配下から "site-{siteId}_*"(前方一致)または "site-{siteId}"(完全一致)の
// フォルダを探す。見つからなければ null。
function findSiteDir(configsDir, siteId) {
if (!fs.existsSync(configsDir)) return null;
const bare = `site-${siteId}`;
const prefix = `site-${siteId}_`;
const candidates = fs.readdirSync(configsDir).filter((name) => {
const full = path.join(configsDir, name);
return fs.statSync(full).isDirectory() && (name === bare || name.startsWith(prefix));
});
const suffixed = candidates.filter((n) => n !== bare);
if (suffixed.length >= 1) return path.join(configsDir, suffixed[0]);
if (candidates.includes(bare)) return path.join(configsDir, bare);
return null;
}
// 既存フォルダがあればそれを使い、無ければ site-{siteId}_{sanitize(title)} を新規作成する
function ensureSiteDir(configsDir, siteId, title) {
const existing = findSiteDir(configsDir, siteId);
if (existing) return existing;
const dir = path.join(configsDir, `site-${siteId}_${sanitize(title)}`);
return ensureDir(dir);
}
function sitesettingsDir(siteDir) {
return ensureDir(path.join(siteDir, "sitesettings"));
}
function docsDir(siteDir) {
return ensureDir(path.join(siteDir, "docs"));
}
// 修正依頼用の新規フォルダを作成するlabelを省略した場合はタイムスタンプを使う
function newModifyDir(siteDir, label) {
const name = label || new Date().toISOString().replace(/[:.]/g, "-");
return ensureDir(path.join(siteDir, "modify", name));
}
// 既存のmodifyフォルダの中で最も新しいものフォルダ名の降順ソートを返す。無ければnull。
function latestModifyDir(siteDir) {
const modifyRoot = path.join(siteDir, "modify");
if (!fs.existsSync(modifyRoot)) return null;
const dirs = fs
.readdirSync(modifyRoot)
.filter((n) => fs.statSync(path.join(modifyRoot, n)).isDirectory())
.sort();
if (dirs.length === 0) return null;
return path.join(modifyRoot, dirs[dirs.length - 1]);
}
// サイトの最新getsiteダンプsite-{siteId}_latest.jsonのパスを返す。
// フォルダ自体が無い場合は null。
function latestJsonPath(configsDir, siteId) {
const siteDir = findSiteDir(configsDir, siteId);
if (!siteDir) return null;
return path.join(siteDir, "sitesettings", `site-${siteId}_latest.json`);
}
module.exports = {
sanitize,
ensureDir,
findSiteDir,
ensureSiteDir,
sitesettingsDir,
docsDir,
newModifyDir,
latestModifyDir,
latestJsonPath,
};