@einja/dev-cli 0.1.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +179 -0
- package/dist/cli.d.ts +2 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +49 -0
- package/dist/cli.js.map +1 -0
- package/dist/commands/init.d.ts +3 -0
- package/dist/commands/init.d.ts.map +1 -0
- package/dist/commands/init.js +243 -0
- package/dist/commands/init.js.map +1 -0
- package/dist/commands/list.d.ts +2 -0
- package/dist/commands/list.d.ts.map +1 -0
- package/dist/commands/list.js +23 -0
- package/dist/commands/list.js.map +1 -0
- package/dist/commands/sync.d.ts +7 -0
- package/dist/commands/sync.d.ts.map +1 -0
- package/dist/commands/sync.js +294 -0
- package/dist/commands/sync.js.map +1 -0
- package/dist/commands/sync.test.d.ts +2 -0
- package/dist/commands/sync.test.d.ts.map +1 -0
- package/dist/commands/sync.test.js +593 -0
- package/dist/commands/sync.test.js.map +1 -0
- package/dist/commands/task-loop.d.ts +11 -0
- package/dist/commands/task-loop.d.ts.map +1 -0
- package/dist/commands/task-loop.js +81 -0
- package/dist/commands/task-loop.js.map +1 -0
- package/dist/index.d.ts +4 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +3 -0
- package/dist/index.js.map +1 -0
- package/dist/lib/file-system.d.ts +39 -0
- package/dist/lib/file-system.d.ts.map +1 -0
- package/dist/lib/file-system.js +79 -0
- package/dist/lib/file-system.js.map +1 -0
- package/dist/lib/mcp-config.d.ts +43 -0
- package/dist/lib/mcp-config.d.ts.map +1 -0
- package/dist/lib/mcp-config.js +109 -0
- package/dist/lib/mcp-config.js.map +1 -0
- package/dist/lib/mcp-config.test.d.ts +2 -0
- package/dist/lib/mcp-config.test.d.ts.map +1 -0
- package/dist/lib/mcp-config.test.js +285 -0
- package/dist/lib/mcp-config.test.js.map +1 -0
- package/dist/lib/merger.d.ts +41 -0
- package/dist/lib/merger.d.ts.map +1 -0
- package/dist/lib/merger.js +164 -0
- package/dist/lib/merger.js.map +1 -0
- package/dist/lib/preset-update/cli-repo-detector.d.ts +35 -0
- package/dist/lib/preset-update/cli-repo-detector.d.ts.map +1 -0
- package/dist/lib/preset-update/cli-repo-detector.js +83 -0
- package/dist/lib/preset-update/cli-repo-detector.js.map +1 -0
- package/dist/lib/preset-update/cli-repo-detector.test.d.ts +2 -0
- package/dist/lib/preset-update/cli-repo-detector.test.d.ts.map +1 -0
- package/dist/lib/preset-update/cli-repo-detector.test.js +120 -0
- package/dist/lib/preset-update/cli-repo-detector.test.js.map +1 -0
- package/dist/lib/preset-update/file-copier.d.ts +59 -0
- package/dist/lib/preset-update/file-copier.d.ts.map +1 -0
- package/dist/lib/preset-update/file-copier.js +220 -0
- package/dist/lib/preset-update/file-copier.js.map +1 -0
- package/dist/lib/preset-update/file-copier.test.d.ts +2 -0
- package/dist/lib/preset-update/file-copier.test.d.ts.map +1 -0
- package/dist/lib/preset-update/file-copier.test.js +297 -0
- package/dist/lib/preset-update/file-copier.test.js.map +1 -0
- package/dist/lib/preset-update/preset-finder.d.ts +39 -0
- package/dist/lib/preset-update/preset-finder.d.ts.map +1 -0
- package/dist/lib/preset-update/preset-finder.js +92 -0
- package/dist/lib/preset-update/preset-finder.js.map +1 -0
- package/dist/lib/preset-update/preset-finder.test.d.ts +2 -0
- package/dist/lib/preset-update/preset-finder.test.d.ts.map +1 -0
- package/dist/lib/preset-update/preset-finder.test.js +128 -0
- package/dist/lib/preset-update/preset-finder.test.js.map +1 -0
- package/dist/lib/preset.d.ts +14 -0
- package/dist/lib/preset.d.ts.map +1 -0
- package/dist/lib/preset.js +52 -0
- package/dist/lib/preset.js.map +1 -0
- package/dist/lib/sync/backup-manager.d.ts +50 -0
- package/dist/lib/sync/backup-manager.d.ts.map +1 -0
- package/dist/lib/sync/backup-manager.js +117 -0
- package/dist/lib/sync/backup-manager.js.map +1 -0
- package/dist/lib/sync/backup-manager.test.d.ts +2 -0
- package/dist/lib/sync/backup-manager.test.d.ts.map +1 -0
- package/dist/lib/sync/backup-manager.test.js +155 -0
- package/dist/lib/sync/backup-manager.test.js.map +1 -0
- package/dist/lib/sync/batch-processor.d.ts +27 -0
- package/dist/lib/sync/batch-processor.d.ts.map +1 -0
- package/dist/lib/sync/batch-processor.js +46 -0
- package/dist/lib/sync/batch-processor.js.map +1 -0
- package/dist/lib/sync/batch-processor.test.d.ts +2 -0
- package/dist/lib/sync/batch-processor.test.d.ts.map +1 -0
- package/dist/lib/sync/batch-processor.test.js +110 -0
- package/dist/lib/sync/batch-processor.test.js.map +1 -0
- package/dist/lib/sync/category-validator.d.ts +36 -0
- package/dist/lib/sync/category-validator.d.ts.map +1 -0
- package/dist/lib/sync/category-validator.js +46 -0
- package/dist/lib/sync/category-validator.js.map +1 -0
- package/dist/lib/sync/category-validator.test.d.ts +2 -0
- package/dist/lib/sync/category-validator.test.d.ts.map +1 -0
- package/dist/lib/sync/category-validator.test.js +89 -0
- package/dist/lib/sync/category-validator.test.js.map +1 -0
- package/dist/lib/sync/conflict-reporter.d.ts +57 -0
- package/dist/lib/sync/conflict-reporter.d.ts.map +1 -0
- package/dist/lib/sync/conflict-reporter.js +81 -0
- package/dist/lib/sync/conflict-reporter.js.map +1 -0
- package/dist/lib/sync/conflict-reporter.test.d.ts +2 -0
- package/dist/lib/sync/conflict-reporter.test.d.ts.map +1 -0
- package/dist/lib/sync/conflict-reporter.test.js +132 -0
- package/dist/lib/sync/conflict-reporter.test.js.map +1 -0
- package/dist/lib/sync/diff-engine.d.ts +28 -0
- package/dist/lib/sync/diff-engine.d.ts.map +1 -0
- package/dist/lib/sync/diff-engine.js +118 -0
- package/dist/lib/sync/diff-engine.js.map +1 -0
- package/dist/lib/sync/diff-engine.test.d.ts +2 -0
- package/dist/lib/sync/diff-engine.test.d.ts.map +1 -0
- package/dist/lib/sync/diff-engine.test.js +133 -0
- package/dist/lib/sync/diff-engine.test.js.map +1 -0
- package/dist/lib/sync/file-filter.d.ts +40 -0
- package/dist/lib/sync/file-filter.d.ts.map +1 -0
- package/dist/lib/sync/file-filter.js +171 -0
- package/dist/lib/sync/file-filter.js.map +1 -0
- package/dist/lib/sync/file-filter.test.d.ts +2 -0
- package/dist/lib/sync/file-filter.test.d.ts.map +1 -0
- package/dist/lib/sync/file-filter.test.js +179 -0
- package/dist/lib/sync/file-filter.test.js.map +1 -0
- package/dist/lib/sync/hash-cache.d.ts +34 -0
- package/dist/lib/sync/hash-cache.d.ts.map +1 -0
- package/dist/lib/sync/hash-cache.js +51 -0
- package/dist/lib/sync/hash-cache.js.map +1 -0
- package/dist/lib/sync/hash-cache.test.d.ts +2 -0
- package/dist/lib/sync/hash-cache.test.d.ts.map +1 -0
- package/dist/lib/sync/hash-cache.test.js +110 -0
- package/dist/lib/sync/hash-cache.test.js.map +1 -0
- package/dist/lib/sync/integration.test.d.ts +2 -0
- package/dist/lib/sync/integration.test.d.ts.map +1 -0
- package/dist/lib/sync/integration.test.js +317 -0
- package/dist/lib/sync/integration.test.js.map +1 -0
- package/dist/lib/sync/marker-processor.d.ts +54 -0
- package/dist/lib/sync/marker-processor.d.ts.map +1 -0
- package/dist/lib/sync/marker-processor.js +208 -0
- package/dist/lib/sync/marker-processor.js.map +1 -0
- package/dist/lib/sync/marker-processor.test.d.ts +2 -0
- package/dist/lib/sync/marker-processor.test.d.ts.map +1 -0
- package/dist/lib/sync/marker-processor.test.js +245 -0
- package/dist/lib/sync/marker-processor.test.js.map +1 -0
- package/dist/lib/sync/metadata-manager.d.ts +46 -0
- package/dist/lib/sync/metadata-manager.d.ts.map +1 -0
- package/dist/lib/sync/metadata-manager.js +129 -0
- package/dist/lib/sync/metadata-manager.js.map +1 -0
- package/dist/lib/sync/metadata-manager.test.d.ts +2 -0
- package/dist/lib/sync/metadata-manager.test.d.ts.map +1 -0
- package/dist/lib/sync/metadata-manager.test.js +137 -0
- package/dist/lib/sync/metadata-manager.test.js.map +1 -0
- package/dist/lib/sync/performance.test.d.ts +2 -0
- package/dist/lib/sync/performance.test.d.ts.map +1 -0
- package/dist/lib/sync/performance.test.js +126 -0
- package/dist/lib/sync/performance.test.js.map +1 -0
- package/dist/types/index.d.ts +59 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/index.js +2 -0
- package/dist/types/index.js.map +1 -0
- package/dist/types/preset-update.d.ts +106 -0
- package/dist/types/preset-update.d.ts.map +1 -0
- package/dist/types/preset-update.js +5 -0
- package/dist/types/preset-update.js.map +1 -0
- package/dist/types/sync.d.ts +169 -0
- package/dist/types/sync.d.ts.map +1 -0
- package/dist/types/sync.js +19 -0
- package/dist/types/sync.js.map +1 -0
- package/package.json +72 -0
- package/presets/minimal/.claude/agents/einja/docs/docs-updater.md +161 -0
- package/presets/minimal/.claude/agents/einja/frontend/design-engineer.md +685 -0
- package/presets/minimal/.claude/agents/einja/frontend/frontend-architect.md +747 -0
- package/presets/minimal/.claude/agents/einja/frontend/frontend-coder.md +441 -0
- package/presets/minimal/.claude/agents/einja/git/conflict-resolver.md +148 -0
- package/presets/minimal/.claude/agents/einja/specs/spec-design-generator.md +462 -0
- package/presets/minimal/.claude/agents/einja/specs/spec-qa-generator.md +466 -0
- package/presets/minimal/.claude/agents/einja/specs/spec-requirements-generator.md +416 -0
- package/presets/minimal/.claude/agents/einja/specs/spec-tasks-generator.md +608 -0
- package/presets/minimal/.claude/agents/einja/task/task-committer.md +82 -0
- package/presets/minimal/.claude/agents/einja/task/task-executer.md +352 -0
- package/presets/minimal/.claude/agents/einja/task/task-modification-analyzer.md +369 -0
- package/presets/minimal/.claude/agents/einja/task/task-qa.md +74 -0
- package/presets/minimal/.claude/agents/einja/task/task-reviewer.md +169 -0
- package/presets/minimal/.claude/commands/einja/frontend-implement.md +322 -0
- package/presets/minimal/.claude/commands/einja/spec-create.md +254 -0
- package/presets/minimal/.claude/commands/einja/start-dev.md +98 -0
- package/presets/minimal/.claude/commands/einja/sync-cursor-commands.md +203 -0
- package/presets/minimal/.claude/commands/einja/task-exec.md +390 -0
- package/presets/minimal/.claude/commands/einja/update-docs-by-task-specs.md +448 -0
- package/presets/minimal/.claude/hooks/einja/biome-format.sh +49 -0
- package/presets/minimal/.claude/hooks/einja/design-doc-check.sh +61 -0
- package/presets/minimal/.claude/hooks/einja/detect-secrets.sh +62 -0
- package/presets/minimal/.claude/hooks/einja/large-file-warning.sh +42 -0
- package/presets/minimal/.claude/hooks/einja/playwright-resize.sh +36 -0
- package/presets/minimal/.claude/hooks/einja/typecheck.sh +37 -0
- package/presets/minimal/.claude/hooks/einja/unset-volta-recursion.sh +32 -0
- package/presets/minimal/.claude/hooks/einja/validate-git-commit.sh +239 -0
- package/presets/minimal/.claude/hooks/einja/warn-index-ts.sh +34 -0
- package/presets/minimal/.claude/hooks/einja/warn-relative-import.sh +48 -0
- package/presets/minimal/.claude/settings.json +174 -0
- package/presets/minimal/.claude/skills/einja/api-development/SKILL.md +14 -0
- package/presets/minimal/.claude/skills/einja/backend-architecture/SKILL.md +14 -0
- package/presets/minimal/.claude/skills/einja/coding-standards/SKILL.md +120 -0
- package/presets/minimal/.claude/skills/einja/coding-standards/reference/naming-conventions.md +107 -0
- package/presets/minimal/.claude/skills/einja/coding-standards/reference/prohibited-patterns.md +169 -0
- package/presets/minimal/.claude/skills/einja/coding-standards/reference/typescript-rules.md +247 -0
- package/presets/minimal/.claude/skills/einja/component-design/SKILL.md +109 -0
- package/presets/minimal/.claude/skills/einja/component-design/reference/directory-structure.md +117 -0
- package/presets/minimal/.claude/skills/einja/component-design/reference/props-patterns.md +159 -0
- package/presets/minimal/.claude/skills/einja/component-design/reference/styling-guide.md +200 -0
- package/presets/minimal/.claude/skills/einja/conflict-resolver/SKILL.md +190 -0
- package/presets/minimal/.claude/skills/einja/frontend-development/SKILL.md +14 -0
- package/presets/minimal/.claude/skills/einja/general-context-loader/SKILL.md +254 -0
- package/presets/minimal/.claude/skills/einja/output-format/SKILL.md +137 -0
- package/presets/minimal/.claude/skills/einja/spec-context-loader/SKILL.md +177 -0
- package/presets/minimal/.claude/skills/einja/task-commit/SKILL.md +269 -0
- package/presets/minimal/.claude/skills/einja/task-qa/SKILL.md +306 -0
- package/presets/minimal/.claude/skills/einja/task-qa/reference/failure-patterns.md +69 -0
- package/presets/minimal/.claude/skills/einja/task-qa/reference/troubleshooting.md +65 -0
- package/presets/minimal/.claude/skills/einja/task-qa/reference/usage-patterns.md +52 -0
- package/presets/minimal/.claude/skills/einja/task-qa/templates/qa-test-template.md +128 -0
- package/presets/minimal/preset.yaml +111 -0
- package/presets/minimal/symlinks.json +45 -0
- package/scaffolds/.mcp.json +45 -0
- package/scaffolds/CLAUDE.md.template +318 -0
- package/scaffolds/steering/README.md +170 -0
- package/scaffolds/steering/acceptance-criteria-and-qa-guide.md +415 -0
- package/scaffolds/steering/architecture.md +481 -0
- package/scaffolds/steering/branch-strategy.md +362 -0
- package/scaffolds/steering/commit-rules.md +217 -0
- package/scaffolds/steering/db-schema-design.md +609 -0
- package/scaffolds/steering/development/api-development.md +783 -0
- package/scaffolds/steering/development/backend-architecture.md +731 -0
- package/scaffolds/steering/development/frontend-development.md +1537 -0
- package/scaffolds/steering/development/review-guidelines.md +365 -0
- package/scaffolds/steering/development/testing-strategy.md +819 -0
- package/scaffolds/steering/development-workflow.md +429 -0
- package/scaffolds/steering/infrastructure/deployment.md +277 -0
- package/scaffolds/steering/infrastructure/environment-variables.md +298 -0
- package/scaffolds/steering/product.md +540 -0
- package/scaffolds/steering/task-management.md +367 -0
- package/templates/README.md +159 -0
- package/templates/design-simple.md.template +172 -0
- package/templates/design.md.template +327 -0
- package/templates/qa-test.md.template +125 -0
- package/templates/requirements.md.template +254 -0
|
@@ -0,0 +1,208 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @einja:managedマーカーの処理を行うクラス
|
|
3
|
+
* マーカーをパースしてセクションを分離し、検証・置換処理を提供します。
|
|
4
|
+
*/
|
|
5
|
+
export class MarkerProcessor {
|
|
6
|
+
/**
|
|
7
|
+
* ファイル内容をパースしてマーカーセクションに分離する
|
|
8
|
+
*
|
|
9
|
+
* @param content - ファイル内容
|
|
10
|
+
* @returns セクション配列(managedとunmanagedが交互に配置される)
|
|
11
|
+
*/
|
|
12
|
+
parseMarkers(content) {
|
|
13
|
+
const lines = content.split("\n");
|
|
14
|
+
const sections = [];
|
|
15
|
+
let currentType = "unmanaged";
|
|
16
|
+
let currentStartLine = 1;
|
|
17
|
+
let currentContent = [];
|
|
18
|
+
let startMarkerLine = 0;
|
|
19
|
+
for (let i = 0; i < lines.length; i++) {
|
|
20
|
+
const line = lines[i];
|
|
21
|
+
const lineNumber = i + 1;
|
|
22
|
+
// マーカー開始を検出
|
|
23
|
+
if (this.isStartMarker(line)) {
|
|
24
|
+
if (currentType === "managed") {
|
|
25
|
+
// 入れ子のマーカーは無視(検証フェーズでエラーになる)
|
|
26
|
+
currentContent.push(line);
|
|
27
|
+
continue;
|
|
28
|
+
}
|
|
29
|
+
// 現在のunmanagedセクションを保存
|
|
30
|
+
if (currentContent.length > 0 || sections.length === 0) {
|
|
31
|
+
sections.push({
|
|
32
|
+
type: "unmanaged",
|
|
33
|
+
startLine: currentStartLine,
|
|
34
|
+
endLine: lineNumber - 1,
|
|
35
|
+
content: currentContent.join("\n"),
|
|
36
|
+
});
|
|
37
|
+
}
|
|
38
|
+
// managedセクション開始
|
|
39
|
+
currentType = "managed";
|
|
40
|
+
startMarkerLine = lineNumber;
|
|
41
|
+
currentStartLine = lineNumber;
|
|
42
|
+
currentContent = [line];
|
|
43
|
+
}
|
|
44
|
+
// マーカー終了を検出
|
|
45
|
+
else if (this.isEndMarker(line)) {
|
|
46
|
+
if (currentType === "unmanaged") {
|
|
47
|
+
// 対応するstartがない場合は無視(検証フェーズでエラーになる)
|
|
48
|
+
currentContent.push(line);
|
|
49
|
+
continue;
|
|
50
|
+
}
|
|
51
|
+
// マーカー終了行を追加
|
|
52
|
+
currentContent.push(line);
|
|
53
|
+
// managedセクションを保存
|
|
54
|
+
sections.push({
|
|
55
|
+
type: "managed",
|
|
56
|
+
startLine: currentStartLine,
|
|
57
|
+
endLine: lineNumber,
|
|
58
|
+
content: currentContent.join("\n"),
|
|
59
|
+
});
|
|
60
|
+
// unmanagedセクション開始
|
|
61
|
+
currentType = "unmanaged";
|
|
62
|
+
currentStartLine = lineNumber + 1;
|
|
63
|
+
currentContent = [];
|
|
64
|
+
}
|
|
65
|
+
// 通常行
|
|
66
|
+
else {
|
|
67
|
+
currentContent.push(line);
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
// 最後のセクションを保存
|
|
71
|
+
if (currentContent.length > 0 || sections.length === 0) {
|
|
72
|
+
sections.push({
|
|
73
|
+
type: currentType,
|
|
74
|
+
startLine: currentStartLine,
|
|
75
|
+
endLine: lines.length,
|
|
76
|
+
content: currentContent.join("\n"),
|
|
77
|
+
});
|
|
78
|
+
}
|
|
79
|
+
return sections;
|
|
80
|
+
}
|
|
81
|
+
/**
|
|
82
|
+
* マーカーペアの検証を行う
|
|
83
|
+
*
|
|
84
|
+
* @param content - ファイル内容
|
|
85
|
+
* @returns 検証結果
|
|
86
|
+
*/
|
|
87
|
+
validateMarkers(content) {
|
|
88
|
+
const lines = content.split("\n");
|
|
89
|
+
const errors = [];
|
|
90
|
+
const startMarkers = [];
|
|
91
|
+
let inManaged = false;
|
|
92
|
+
for (let i = 0; i < lines.length; i++) {
|
|
93
|
+
const line = lines[i];
|
|
94
|
+
const lineNumber = i + 1;
|
|
95
|
+
if (this.isStartMarker(line)) {
|
|
96
|
+
if (inManaged) {
|
|
97
|
+
// 入れ子のマーカー - エラーを記録するがstackには追加しない
|
|
98
|
+
errors.push({
|
|
99
|
+
line: lineNumber,
|
|
100
|
+
message: "@einja:managedマーカーのネストは許可されていません",
|
|
101
|
+
type: "nested",
|
|
102
|
+
});
|
|
103
|
+
// ネストマーカーを無視して処理を続行
|
|
104
|
+
continue;
|
|
105
|
+
}
|
|
106
|
+
startMarkers.push(lineNumber);
|
|
107
|
+
inManaged = true;
|
|
108
|
+
}
|
|
109
|
+
else if (this.isEndMarker(line)) {
|
|
110
|
+
if (!inManaged || startMarkers.length === 0) {
|
|
111
|
+
// 対応するstartがない
|
|
112
|
+
errors.push({
|
|
113
|
+
line: lineNumber,
|
|
114
|
+
message: "対応する@einja:managed:startが見つかりません",
|
|
115
|
+
type: "unpaired_end",
|
|
116
|
+
});
|
|
117
|
+
}
|
|
118
|
+
else {
|
|
119
|
+
startMarkers.pop();
|
|
120
|
+
inManaged = false;
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
// 未閉じのstartマーカー
|
|
125
|
+
for (const lineNumber of startMarkers) {
|
|
126
|
+
errors.push({
|
|
127
|
+
line: lineNumber,
|
|
128
|
+
message: "対応する@einja:managed:endが見つかりません",
|
|
129
|
+
type: "unpaired_start",
|
|
130
|
+
});
|
|
131
|
+
}
|
|
132
|
+
return {
|
|
133
|
+
valid: errors.length === 0,
|
|
134
|
+
errors,
|
|
135
|
+
};
|
|
136
|
+
}
|
|
137
|
+
/**
|
|
138
|
+
* マーカー内セクションをテンプレート版で置換する
|
|
139
|
+
*
|
|
140
|
+
* @param localSections - ローカル版のセクション配列
|
|
141
|
+
* @param templateContent - テンプレート版の内容
|
|
142
|
+
* @returns 置換後の内容
|
|
143
|
+
*/
|
|
144
|
+
replaceManaged(localSections, templateContent) {
|
|
145
|
+
const templateSections = this.parseMarkers(templateContent);
|
|
146
|
+
const result = [];
|
|
147
|
+
// セクション数が一致しない場合、ローカル版のセクションを優先
|
|
148
|
+
// (テンプレート側でマーカーが削除された可能性があるため)
|
|
149
|
+
const maxSections = Math.max(localSections.length, templateSections.length);
|
|
150
|
+
for (let i = 0; i < maxSections; i++) {
|
|
151
|
+
const localSection = localSections[i];
|
|
152
|
+
const templateSection = templateSections[i];
|
|
153
|
+
if (!localSection) {
|
|
154
|
+
// テンプレート側にのみ存在するセクションを追加
|
|
155
|
+
if (templateSection) {
|
|
156
|
+
result.push(templateSection.content);
|
|
157
|
+
}
|
|
158
|
+
continue;
|
|
159
|
+
}
|
|
160
|
+
if (localSection.type === "managed") {
|
|
161
|
+
// managedセクションはテンプレート版で置換
|
|
162
|
+
if (templateSection && templateSection.type === "managed") {
|
|
163
|
+
result.push(templateSection.content);
|
|
164
|
+
}
|
|
165
|
+
else {
|
|
166
|
+
// テンプレート側にmanagedセクションがない場合はローカルを保持
|
|
167
|
+
result.push(localSection.content);
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
else {
|
|
171
|
+
// unmanagedセクションはローカル版を保持
|
|
172
|
+
result.push(localSection.content);
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
return result.join("\n");
|
|
176
|
+
}
|
|
177
|
+
/**
|
|
178
|
+
* 行がマーカー開始かどうかを判定する
|
|
179
|
+
*
|
|
180
|
+
* @param line - 行内容
|
|
181
|
+
* @returns マーカー開始の場合true
|
|
182
|
+
*/
|
|
183
|
+
isStartMarker(line) {
|
|
184
|
+
return (MarkerProcessor.MARKDOWN_START_PATTERN.test(line) ||
|
|
185
|
+
MarkerProcessor.YAML_START_PATTERN.test(line));
|
|
186
|
+
}
|
|
187
|
+
/**
|
|
188
|
+
* 行がマーカー終了かどうかを判定する
|
|
189
|
+
*
|
|
190
|
+
* @param line - 行内容
|
|
191
|
+
* @returns マーカー終了の場合true
|
|
192
|
+
*/
|
|
193
|
+
isEndMarker(line) {
|
|
194
|
+
return (MarkerProcessor.MARKDOWN_END_PATTERN.test(line) ||
|
|
195
|
+
MarkerProcessor.YAML_END_PATTERN.test(line));
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
/**
|
|
199
|
+
* Markdownファイル用のマーカーパターン
|
|
200
|
+
*/
|
|
201
|
+
MarkerProcessor.MARKDOWN_START_PATTERN = /^<!--\s*@einja:managed:start\s*-->$/;
|
|
202
|
+
MarkerProcessor.MARKDOWN_END_PATTERN = /^<!--\s*@einja:managed:end\s*-->$/;
|
|
203
|
+
/**
|
|
204
|
+
* YAML/JSONファイル用のマーカーパターン
|
|
205
|
+
*/
|
|
206
|
+
MarkerProcessor.YAML_START_PATTERN = /^\s*#\s*@einja:managed:start\s*$/;
|
|
207
|
+
MarkerProcessor.YAML_END_PATTERN = /^\s*#\s*@einja:managed:end\s*$/;
|
|
208
|
+
//# sourceMappingURL=marker-processor.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"marker-processor.js","sourceRoot":"","sources":["../../../src/lib/sync/marker-processor.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"marker-processor.test.d.ts","sourceRoot":"","sources":["../../../src/lib/sync/marker-processor.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,245 @@
|
|
|
1
|
+
import { describe, expect, it } from "vitest";
|
|
2
|
+
import { MarkerProcessor } from "./marker-processor.js";
|
|
3
|
+
describe("MarkerProcessor", () => {
|
|
4
|
+
const processor = new MarkerProcessor();
|
|
5
|
+
describe("parseMarkers", () => {
|
|
6
|
+
it("マーカーが存在しない場合、全体をunmanagedセクションとして返すこと", () => {
|
|
7
|
+
const content = `行1
|
|
8
|
+
行2
|
|
9
|
+
行3`;
|
|
10
|
+
const sections = processor.parseMarkers(content);
|
|
11
|
+
expect(sections).toHaveLength(1);
|
|
12
|
+
expect(sections[0]).toEqual({
|
|
13
|
+
type: "unmanaged",
|
|
14
|
+
startLine: 1,
|
|
15
|
+
endLine: 3,
|
|
16
|
+
content: "行1\n行2\n行3",
|
|
17
|
+
});
|
|
18
|
+
});
|
|
19
|
+
it("Markdownマーカーで囲まれたセクションをmanagedとして認識すること", () => {
|
|
20
|
+
const content = `行1
|
|
21
|
+
<!-- @einja:managed:start -->
|
|
22
|
+
管理セクション
|
|
23
|
+
<!-- @einja:managed:end -->
|
|
24
|
+
行2`;
|
|
25
|
+
const sections = processor.parseMarkers(content);
|
|
26
|
+
expect(sections).toHaveLength(3);
|
|
27
|
+
expect(sections[0].type).toBe("unmanaged");
|
|
28
|
+
expect(sections[0].content).toBe("行1");
|
|
29
|
+
expect(sections[1].type).toBe("managed");
|
|
30
|
+
expect(sections[1].content).toBe("<!-- @einja:managed:start -->\n管理セクション\n<!-- @einja:managed:end -->");
|
|
31
|
+
expect(sections[2].type).toBe("unmanaged");
|
|
32
|
+
expect(sections[2].content).toBe("行2");
|
|
33
|
+
});
|
|
34
|
+
it("YAMLマーカーで囲まれたセクションをmanagedとして認識すること", () => {
|
|
35
|
+
const content = `設定1: value1
|
|
36
|
+
# @einja:managed:start
|
|
37
|
+
管理設定: value
|
|
38
|
+
# @einja:managed:end
|
|
39
|
+
設定2: value2`;
|
|
40
|
+
const sections = processor.parseMarkers(content);
|
|
41
|
+
expect(sections).toHaveLength(3);
|
|
42
|
+
expect(sections[0].type).toBe("unmanaged");
|
|
43
|
+
expect(sections[1].type).toBe("managed");
|
|
44
|
+
expect(sections[1].content).toBe("# @einja:managed:start\n管理設定: value\n# @einja:managed:end");
|
|
45
|
+
expect(sections[2].type).toBe("unmanaged");
|
|
46
|
+
});
|
|
47
|
+
it("複数のmanagedセクションを正しく分離すること", () => {
|
|
48
|
+
const content = `行1
|
|
49
|
+
<!-- @einja:managed:start -->
|
|
50
|
+
管理セクション1
|
|
51
|
+
<!-- @einja:managed:end -->
|
|
52
|
+
行2
|
|
53
|
+
<!-- @einja:managed:start -->
|
|
54
|
+
管理セクション2
|
|
55
|
+
<!-- @einja:managed:end -->
|
|
56
|
+
行3`;
|
|
57
|
+
const sections = processor.parseMarkers(content);
|
|
58
|
+
expect(sections).toHaveLength(5);
|
|
59
|
+
expect(sections[0].type).toBe("unmanaged");
|
|
60
|
+
expect(sections[1].type).toBe("managed");
|
|
61
|
+
expect(sections[2].type).toBe("unmanaged");
|
|
62
|
+
expect(sections[3].type).toBe("managed");
|
|
63
|
+
expect(sections[4].type).toBe("unmanaged");
|
|
64
|
+
});
|
|
65
|
+
it("行番号が正しく設定されること", () => {
|
|
66
|
+
const content = `行1
|
|
67
|
+
行2
|
|
68
|
+
<!-- @einja:managed:start -->
|
|
69
|
+
管理セクション
|
|
70
|
+
<!-- @einja:managed:end -->
|
|
71
|
+
行3`;
|
|
72
|
+
const sections = processor.parseMarkers(content);
|
|
73
|
+
expect(sections[0].startLine).toBe(1);
|
|
74
|
+
expect(sections[0].endLine).toBe(2);
|
|
75
|
+
expect(sections[1].startLine).toBe(3);
|
|
76
|
+
expect(sections[1].endLine).toBe(5);
|
|
77
|
+
expect(sections[2].startLine).toBe(6);
|
|
78
|
+
expect(sections[2].endLine).toBe(6);
|
|
79
|
+
});
|
|
80
|
+
});
|
|
81
|
+
describe("validateMarkers", () => {
|
|
82
|
+
it("正しいマーカーペアの場合、validがtrueであること", () => {
|
|
83
|
+
const content = `行1
|
|
84
|
+
<!-- @einja:managed:start -->
|
|
85
|
+
管理セクション
|
|
86
|
+
<!-- @einja:managed:end -->
|
|
87
|
+
行2`;
|
|
88
|
+
const result = processor.validateMarkers(content);
|
|
89
|
+
expect(result.valid).toBe(true);
|
|
90
|
+
expect(result.errors).toHaveLength(0);
|
|
91
|
+
});
|
|
92
|
+
it("startマーカーのみの場合、unpaired_startエラーを返すこと", () => {
|
|
93
|
+
const content = `行1
|
|
94
|
+
<!-- @einja:managed:start -->
|
|
95
|
+
管理セクション
|
|
96
|
+
行2`;
|
|
97
|
+
const result = processor.validateMarkers(content);
|
|
98
|
+
expect(result.valid).toBe(false);
|
|
99
|
+
expect(result.errors).toHaveLength(1);
|
|
100
|
+
expect(result.errors[0].type).toBe("unpaired_start");
|
|
101
|
+
expect(result.errors[0].line).toBe(2);
|
|
102
|
+
expect(result.errors[0].message).toBe("対応する@einja:managed:endが見つかりません");
|
|
103
|
+
});
|
|
104
|
+
it("endマーカーのみの場合、unpaired_endエラーを返すこと", () => {
|
|
105
|
+
const content = `行1
|
|
106
|
+
管理セクション
|
|
107
|
+
<!-- @einja:managed:end -->
|
|
108
|
+
行2`;
|
|
109
|
+
const result = processor.validateMarkers(content);
|
|
110
|
+
expect(result.valid).toBe(false);
|
|
111
|
+
expect(result.errors).toHaveLength(1);
|
|
112
|
+
expect(result.errors[0].type).toBe("unpaired_end");
|
|
113
|
+
expect(result.errors[0].line).toBe(3);
|
|
114
|
+
expect(result.errors[0].message).toBe("対応する@einja:managed:startが見つかりません");
|
|
115
|
+
});
|
|
116
|
+
it("ネストしたマーカーの場合、nestedエラーを返すこと", () => {
|
|
117
|
+
const content = `行1
|
|
118
|
+
<!-- @einja:managed:start -->
|
|
119
|
+
外側
|
|
120
|
+
<!-- @einja:managed:start -->
|
|
121
|
+
内側
|
|
122
|
+
<!-- @einja:managed:end -->
|
|
123
|
+
<!-- @einja:managed:end -->
|
|
124
|
+
行2`;
|
|
125
|
+
const result = processor.validateMarkers(content);
|
|
126
|
+
expect(result.valid).toBe(false);
|
|
127
|
+
// ネストマーカーのエラーと、2つ目のendマーカーの対応なしエラーの2つ
|
|
128
|
+
expect(result.errors).toHaveLength(2);
|
|
129
|
+
expect(result.errors[0].type).toBe("nested");
|
|
130
|
+
expect(result.errors[0].line).toBe(4);
|
|
131
|
+
expect(result.errors[0].message).toBe("@einja:managedマーカーのネストは許可されていません");
|
|
132
|
+
expect(result.errors[1].type).toBe("unpaired_end");
|
|
133
|
+
expect(result.errors[1].line).toBe(7);
|
|
134
|
+
});
|
|
135
|
+
it("複数のエラーを検出できること", () => {
|
|
136
|
+
const content = `行1
|
|
137
|
+
<!-- @einja:managed:start -->
|
|
138
|
+
管理セクション1
|
|
139
|
+
行2
|
|
140
|
+
<!-- @einja:managed:end -->
|
|
141
|
+
行3
|
|
142
|
+
<!-- @einja:managed:start -->
|
|
143
|
+
管理セクション2`;
|
|
144
|
+
const result = processor.validateMarkers(content);
|
|
145
|
+
expect(result.valid).toBe(false);
|
|
146
|
+
// 最初のペアは正しいが、2つ目のstartに対応するendがない
|
|
147
|
+
expect(result.errors).toHaveLength(1);
|
|
148
|
+
expect(result.errors[0].type).toBe("unpaired_start");
|
|
149
|
+
expect(result.errors[0].line).toBe(7);
|
|
150
|
+
});
|
|
151
|
+
});
|
|
152
|
+
describe("replaceManaged", () => {
|
|
153
|
+
it("managedセクションがテンプレート版で上書きされること", () => {
|
|
154
|
+
const localContent = `行1
|
|
155
|
+
<!-- @einja:managed:start -->
|
|
156
|
+
ローカル管理セクション
|
|
157
|
+
<!-- @einja:managed:end -->
|
|
158
|
+
行2`;
|
|
159
|
+
const templateContent = `行1
|
|
160
|
+
<!-- @einja:managed:start -->
|
|
161
|
+
テンプレート管理セクション
|
|
162
|
+
<!-- @einja:managed:end -->
|
|
163
|
+
行2`;
|
|
164
|
+
const localSections = processor.parseMarkers(localContent);
|
|
165
|
+
const result = processor.replaceManaged(localSections, templateContent);
|
|
166
|
+
expect(result).toContain("テンプレート管理セクション");
|
|
167
|
+
expect(result).not.toContain("ローカル管理セクション");
|
|
168
|
+
});
|
|
169
|
+
it("unmanagedセクションはローカル版が保持されること", () => {
|
|
170
|
+
const localContent = `ローカル行1
|
|
171
|
+
<!-- @einja:managed:start -->
|
|
172
|
+
ローカル管理セクション
|
|
173
|
+
<!-- @einja:managed:end -->
|
|
174
|
+
ローカル行2`;
|
|
175
|
+
const templateContent = `テンプレート行1
|
|
176
|
+
<!-- @einja:managed:start -->
|
|
177
|
+
テンプレート管理セクション
|
|
178
|
+
<!-- @einja:managed:end -->
|
|
179
|
+
テンプレート行2`;
|
|
180
|
+
const localSections = processor.parseMarkers(localContent);
|
|
181
|
+
const result = processor.replaceManaged(localSections, templateContent);
|
|
182
|
+
expect(result).toContain("ローカル行1");
|
|
183
|
+
expect(result).toContain("ローカル行2");
|
|
184
|
+
expect(result).toContain("テンプレート管理セクション");
|
|
185
|
+
expect(result).not.toContain("テンプレート行1");
|
|
186
|
+
expect(result).not.toContain("テンプレート行2");
|
|
187
|
+
});
|
|
188
|
+
it("複数のmanagedセクションが正しく置換されること", () => {
|
|
189
|
+
const localContent = `ローカル行1
|
|
190
|
+
<!-- @einja:managed:start -->
|
|
191
|
+
ローカル管理1
|
|
192
|
+
<!-- @einja:managed:end -->
|
|
193
|
+
ローカル行2
|
|
194
|
+
<!-- @einja:managed:start -->
|
|
195
|
+
ローカル管理2
|
|
196
|
+
<!-- @einja:managed:end -->
|
|
197
|
+
ローカル行3`;
|
|
198
|
+
const templateContent = `テンプレート行1
|
|
199
|
+
<!-- @einja:managed:start -->
|
|
200
|
+
テンプレート管理1
|
|
201
|
+
<!-- @einja:managed:end -->
|
|
202
|
+
テンプレート行2
|
|
203
|
+
<!-- @einja:managed:start -->
|
|
204
|
+
テンプレート管理2
|
|
205
|
+
<!-- @einja:managed:end -->
|
|
206
|
+
テンプレート行3`;
|
|
207
|
+
const localSections = processor.parseMarkers(localContent);
|
|
208
|
+
const result = processor.replaceManaged(localSections, templateContent);
|
|
209
|
+
expect(result).toContain("テンプレート管理1");
|
|
210
|
+
expect(result).toContain("テンプレート管理2");
|
|
211
|
+
expect(result).toContain("ローカル行1");
|
|
212
|
+
expect(result).toContain("ローカル行2");
|
|
213
|
+
expect(result).toContain("ローカル行3");
|
|
214
|
+
expect(result).not.toContain("ローカル管理1");
|
|
215
|
+
expect(result).not.toContain("ローカル管理2");
|
|
216
|
+
});
|
|
217
|
+
it("マーカーがない場合、ローカル版がそのまま保持されること", () => {
|
|
218
|
+
const localContent = `ローカル行1
|
|
219
|
+
ローカル行2
|
|
220
|
+
ローカル行3`;
|
|
221
|
+
const templateContent = `テンプレート行1
|
|
222
|
+
テンプレート行2
|
|
223
|
+
テンプレート行3`;
|
|
224
|
+
const localSections = processor.parseMarkers(localContent);
|
|
225
|
+
const result = processor.replaceManaged(localSections, templateContent);
|
|
226
|
+
expect(result).toBe(localContent);
|
|
227
|
+
});
|
|
228
|
+
it("テンプレート側でマーカーが削除された場合、ローカル版が保持されること", () => {
|
|
229
|
+
const localContent = `ローカル行1
|
|
230
|
+
<!-- @einja:managed:start -->
|
|
231
|
+
ローカル管理セクション
|
|
232
|
+
<!-- @einja:managed:end -->
|
|
233
|
+
ローカル行2`;
|
|
234
|
+
const templateContent = `テンプレート行1
|
|
235
|
+
テンプレート行2`;
|
|
236
|
+
const localSections = processor.parseMarkers(localContent);
|
|
237
|
+
const result = processor.replaceManaged(localSections, templateContent);
|
|
238
|
+
// テンプレート側にmanagedセクションがない場合、ローカルのmanagedセクションを保持
|
|
239
|
+
expect(result).toContain("ローカル管理セクション");
|
|
240
|
+
expect(result).toContain("ローカル行1");
|
|
241
|
+
expect(result).toContain("ローカル行2");
|
|
242
|
+
});
|
|
243
|
+
});
|
|
244
|
+
});
|
|
245
|
+
//# sourceMappingURL=marker-processor.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"marker-processor.test.js","sourceRoot":"","sources":["../../../src/lib/sync/marker-processor.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import type { BaseContent, SyncMetadata } from "../../types/sync.js";
|
|
2
|
+
import { HashCache } from "./hash-cache.js";
|
|
3
|
+
/**
|
|
4
|
+
* メタデータ管理クラス
|
|
5
|
+
* .einja-sync.jsonファイルの読み込み・保存・検証を担当
|
|
6
|
+
*/
|
|
7
|
+
export declare class MetadataManager {
|
|
8
|
+
private metadataPath;
|
|
9
|
+
private hashCache;
|
|
10
|
+
constructor(projectRoot: string, hashCache?: HashCache);
|
|
11
|
+
/**
|
|
12
|
+
* メタデータファイルを読み込む
|
|
13
|
+
* ファイルが存在しない場合は初期値を返す
|
|
14
|
+
*/
|
|
15
|
+
load(): Promise<SyncMetadata>;
|
|
16
|
+
/**
|
|
17
|
+
* メタデータファイルに保存する
|
|
18
|
+
*/
|
|
19
|
+
save(metadata: SyncMetadata): Promise<void>;
|
|
20
|
+
/**
|
|
21
|
+
* メタデータの妥当性を検証する
|
|
22
|
+
*/
|
|
23
|
+
validate(data: unknown): SyncMetadata;
|
|
24
|
+
/**
|
|
25
|
+
* ファイルのベースコンテンツとハッシュを取得する
|
|
26
|
+
*/
|
|
27
|
+
getBaseContent(filePath: string): Promise<BaseContent>;
|
|
28
|
+
/**
|
|
29
|
+
* ファイルハッシュを更新する
|
|
30
|
+
*/
|
|
31
|
+
updateFileHash(metadata: SyncMetadata, filePath: string, content: string): Promise<SyncMetadata>;
|
|
32
|
+
/**
|
|
33
|
+
* SHA-256ハッシュを計算する(キャッシュあり)
|
|
34
|
+
* 同一ファイル内容の場合、2回目以降はキャッシュから取得
|
|
35
|
+
*/
|
|
36
|
+
calculateHash(content: string, filePath?: string): string;
|
|
37
|
+
/**
|
|
38
|
+
* ハッシュキャッシュをクリアする
|
|
39
|
+
*/
|
|
40
|
+
clearHashCache(): void;
|
|
41
|
+
/**
|
|
42
|
+
* デフォルトのメタデータを返す
|
|
43
|
+
*/
|
|
44
|
+
private getDefaultMetadata;
|
|
45
|
+
}
|
|
46
|
+
//# sourceMappingURL=metadata-manager.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"metadata-manager.d.ts","sourceRoot":"","sources":["../../../src/lib/sync/metadata-manager.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EACX,WAAW,EAEX,YAAY,EACZ,MAAM,qBAAqB,CAAC;AAE7B,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAE5C;;;GAGG;AACH,qBAAa,eAAe;IAC3B,OAAO,CAAC,YAAY,CAAS;IAC7B,OAAO,CAAC,SAAS,CAAY;gBAEjB,WAAW,EAAE,MAAM,EAAE,SAAS,CAAC,EAAE,SAAS;IAKtD;;;OAGG;IACG,IAAI,IAAI,OAAO,CAAC,YAAY,CAAC;IAiBnC;;OAEG;IACG,IAAI,CAAC,QAAQ,EAAE,YAAY,GAAG,OAAO,CAAC,IAAI,CAAC;IAgBjD;;OAEG;IACH,QAAQ,CAAC,IAAI,EAAE,OAAO,GAAG,YAAY;IAWrC;;OAEG;IACG,cAAc,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,WAAW,CAAC;IAe5D;;OAEG;IACG,cAAc,CACnB,QAAQ,EAAE,YAAY,EACtB,QAAQ,EAAE,MAAM,EAChB,OAAO,EAAE,MAAM,GACb,OAAO,CAAC,YAAY,CAAC;IAgBxB;;;OAGG;IACH,aAAa,CAAC,OAAO,EAAE,MAAM,EAAE,QAAQ,SAAK,GAAG,MAAM;IAsBrD;;OAEG;IACH,cAAc,IAAI,IAAI;IAItB;;OAEG;IACH,OAAO,CAAC,kBAAkB;CAQ1B"}
|
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
import { createHash } from "node:crypto";
|
|
2
|
+
import fs from "fs-extra";
|
|
3
|
+
import { SyncMetadataSchema } from "../../types/sync.js";
|
|
4
|
+
import { HashCache } from "./hash-cache.js";
|
|
5
|
+
/**
|
|
6
|
+
* メタデータ管理クラス
|
|
7
|
+
* .einja-sync.jsonファイルの読み込み・保存・検証を担当
|
|
8
|
+
*/
|
|
9
|
+
export class MetadataManager {
|
|
10
|
+
constructor(projectRoot, hashCache) {
|
|
11
|
+
this.metadataPath = `${projectRoot}/.einja-sync.json`;
|
|
12
|
+
this.hashCache = hashCache !== null && hashCache !== void 0 ? hashCache : new HashCache();
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* メタデータファイルを読み込む
|
|
16
|
+
* ファイルが存在しない場合は初期値を返す
|
|
17
|
+
*/
|
|
18
|
+
async load() {
|
|
19
|
+
try {
|
|
20
|
+
if (!(await fs.pathExists(this.metadataPath))) {
|
|
21
|
+
return this.getDefaultMetadata();
|
|
22
|
+
}
|
|
23
|
+
const content = await fs.readFile(this.metadataPath, "utf-8");
|
|
24
|
+
const data = JSON.parse(content);
|
|
25
|
+
return this.validate(data);
|
|
26
|
+
}
|
|
27
|
+
catch (error) {
|
|
28
|
+
if (error instanceof Error) {
|
|
29
|
+
throw new Error(`メタデータの読み込みに失敗しました: ${error.message}`);
|
|
30
|
+
}
|
|
31
|
+
throw error;
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* メタデータファイルに保存する
|
|
36
|
+
*/
|
|
37
|
+
async save(metadata) {
|
|
38
|
+
try {
|
|
39
|
+
const validated = this.validate(metadata);
|
|
40
|
+
await fs.writeFile(this.metadataPath, JSON.stringify(validated, null, 2), "utf-8");
|
|
41
|
+
}
|
|
42
|
+
catch (error) {
|
|
43
|
+
if (error instanceof Error) {
|
|
44
|
+
throw new Error(`メタデータの保存に失敗しました: ${error.message}`);
|
|
45
|
+
}
|
|
46
|
+
throw error;
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* メタデータの妥当性を検証する
|
|
51
|
+
*/
|
|
52
|
+
validate(data) {
|
|
53
|
+
try {
|
|
54
|
+
return SyncMetadataSchema.parse(data);
|
|
55
|
+
}
|
|
56
|
+
catch (error) {
|
|
57
|
+
if (error instanceof Error) {
|
|
58
|
+
throw new Error(`メタデータのバリデーションに失敗しました: ${error.message}`);
|
|
59
|
+
}
|
|
60
|
+
throw error;
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* ファイルのベースコンテンツとハッシュを取得する
|
|
65
|
+
*/
|
|
66
|
+
async getBaseContent(filePath) {
|
|
67
|
+
try {
|
|
68
|
+
const content = await fs.readFile(filePath, "utf-8");
|
|
69
|
+
const hash = this.calculateHash(content, filePath);
|
|
70
|
+
return { content, hash };
|
|
71
|
+
}
|
|
72
|
+
catch (error) {
|
|
73
|
+
if (error instanceof Error) {
|
|
74
|
+
throw new Error(`ファイル「${filePath}」の読み込みに失敗しました: ${error.message}`);
|
|
75
|
+
}
|
|
76
|
+
throw error;
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
/**
|
|
80
|
+
* ファイルハッシュを更新する
|
|
81
|
+
*/
|
|
82
|
+
async updateFileHash(metadata, filePath, content) {
|
|
83
|
+
const hash = this.calculateHash(content, filePath);
|
|
84
|
+
const fileMetadata = {
|
|
85
|
+
hash,
|
|
86
|
+
syncedAt: new Date().toISOString(),
|
|
87
|
+
};
|
|
88
|
+
return Object.assign(Object.assign({}, metadata), { files: Object.assign(Object.assign({}, metadata.files), { [filePath]: fileMetadata }) });
|
|
89
|
+
}
|
|
90
|
+
/**
|
|
91
|
+
* SHA-256ハッシュを計算する(キャッシュあり)
|
|
92
|
+
* 同一ファイル内容の場合、2回目以降はキャッシュから取得
|
|
93
|
+
*/
|
|
94
|
+
calculateHash(content, filePath = "") {
|
|
95
|
+
const contentLength = content.length;
|
|
96
|
+
// キャッシュヒット判定
|
|
97
|
+
if (filePath && this.hashCache.has(filePath, contentLength)) {
|
|
98
|
+
const cachedHash = this.hashCache.get(filePath, contentLength);
|
|
99
|
+
if (cachedHash) {
|
|
100
|
+
return cachedHash;
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
// ハッシュ計算
|
|
104
|
+
const hash = createHash("sha256").update(content, "utf8").digest("hex");
|
|
105
|
+
// キャッシュに保存
|
|
106
|
+
if (filePath) {
|
|
107
|
+
this.hashCache.set(filePath, contentLength, hash);
|
|
108
|
+
}
|
|
109
|
+
return hash;
|
|
110
|
+
}
|
|
111
|
+
/**
|
|
112
|
+
* ハッシュキャッシュをクリアする
|
|
113
|
+
*/
|
|
114
|
+
clearHashCache() {
|
|
115
|
+
this.hashCache.clear();
|
|
116
|
+
}
|
|
117
|
+
/**
|
|
118
|
+
* デフォルトのメタデータを返す
|
|
119
|
+
*/
|
|
120
|
+
getDefaultMetadata() {
|
|
121
|
+
return {
|
|
122
|
+
version: "1.0.0",
|
|
123
|
+
lastSync: new Date().toISOString(),
|
|
124
|
+
templateVersion: "0.1.0",
|
|
125
|
+
files: {},
|
|
126
|
+
};
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
//# sourceMappingURL=metadata-manager.js.map
|