@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.
Files changed (243) hide show
  1. package/README.md +179 -0
  2. package/dist/cli.d.ts +2 -0
  3. package/dist/cli.d.ts.map +1 -0
  4. package/dist/cli.js +49 -0
  5. package/dist/cli.js.map +1 -0
  6. package/dist/commands/init.d.ts +3 -0
  7. package/dist/commands/init.d.ts.map +1 -0
  8. package/dist/commands/init.js +243 -0
  9. package/dist/commands/init.js.map +1 -0
  10. package/dist/commands/list.d.ts +2 -0
  11. package/dist/commands/list.d.ts.map +1 -0
  12. package/dist/commands/list.js +23 -0
  13. package/dist/commands/list.js.map +1 -0
  14. package/dist/commands/sync.d.ts +7 -0
  15. package/dist/commands/sync.d.ts.map +1 -0
  16. package/dist/commands/sync.js +294 -0
  17. package/dist/commands/sync.js.map +1 -0
  18. package/dist/commands/sync.test.d.ts +2 -0
  19. package/dist/commands/sync.test.d.ts.map +1 -0
  20. package/dist/commands/sync.test.js +593 -0
  21. package/dist/commands/sync.test.js.map +1 -0
  22. package/dist/commands/task-loop.d.ts +11 -0
  23. package/dist/commands/task-loop.d.ts.map +1 -0
  24. package/dist/commands/task-loop.js +81 -0
  25. package/dist/commands/task-loop.js.map +1 -0
  26. package/dist/index.d.ts +4 -0
  27. package/dist/index.d.ts.map +1 -0
  28. package/dist/index.js +3 -0
  29. package/dist/index.js.map +1 -0
  30. package/dist/lib/file-system.d.ts +39 -0
  31. package/dist/lib/file-system.d.ts.map +1 -0
  32. package/dist/lib/file-system.js +79 -0
  33. package/dist/lib/file-system.js.map +1 -0
  34. package/dist/lib/mcp-config.d.ts +43 -0
  35. package/dist/lib/mcp-config.d.ts.map +1 -0
  36. package/dist/lib/mcp-config.js +109 -0
  37. package/dist/lib/mcp-config.js.map +1 -0
  38. package/dist/lib/mcp-config.test.d.ts +2 -0
  39. package/dist/lib/mcp-config.test.d.ts.map +1 -0
  40. package/dist/lib/mcp-config.test.js +285 -0
  41. package/dist/lib/mcp-config.test.js.map +1 -0
  42. package/dist/lib/merger.d.ts +41 -0
  43. package/dist/lib/merger.d.ts.map +1 -0
  44. package/dist/lib/merger.js +164 -0
  45. package/dist/lib/merger.js.map +1 -0
  46. package/dist/lib/preset-update/cli-repo-detector.d.ts +35 -0
  47. package/dist/lib/preset-update/cli-repo-detector.d.ts.map +1 -0
  48. package/dist/lib/preset-update/cli-repo-detector.js +83 -0
  49. package/dist/lib/preset-update/cli-repo-detector.js.map +1 -0
  50. package/dist/lib/preset-update/cli-repo-detector.test.d.ts +2 -0
  51. package/dist/lib/preset-update/cli-repo-detector.test.d.ts.map +1 -0
  52. package/dist/lib/preset-update/cli-repo-detector.test.js +120 -0
  53. package/dist/lib/preset-update/cli-repo-detector.test.js.map +1 -0
  54. package/dist/lib/preset-update/file-copier.d.ts +59 -0
  55. package/dist/lib/preset-update/file-copier.d.ts.map +1 -0
  56. package/dist/lib/preset-update/file-copier.js +220 -0
  57. package/dist/lib/preset-update/file-copier.js.map +1 -0
  58. package/dist/lib/preset-update/file-copier.test.d.ts +2 -0
  59. package/dist/lib/preset-update/file-copier.test.d.ts.map +1 -0
  60. package/dist/lib/preset-update/file-copier.test.js +297 -0
  61. package/dist/lib/preset-update/file-copier.test.js.map +1 -0
  62. package/dist/lib/preset-update/preset-finder.d.ts +39 -0
  63. package/dist/lib/preset-update/preset-finder.d.ts.map +1 -0
  64. package/dist/lib/preset-update/preset-finder.js +92 -0
  65. package/dist/lib/preset-update/preset-finder.js.map +1 -0
  66. package/dist/lib/preset-update/preset-finder.test.d.ts +2 -0
  67. package/dist/lib/preset-update/preset-finder.test.d.ts.map +1 -0
  68. package/dist/lib/preset-update/preset-finder.test.js +128 -0
  69. package/dist/lib/preset-update/preset-finder.test.js.map +1 -0
  70. package/dist/lib/preset.d.ts +14 -0
  71. package/dist/lib/preset.d.ts.map +1 -0
  72. package/dist/lib/preset.js +52 -0
  73. package/dist/lib/preset.js.map +1 -0
  74. package/dist/lib/sync/backup-manager.d.ts +50 -0
  75. package/dist/lib/sync/backup-manager.d.ts.map +1 -0
  76. package/dist/lib/sync/backup-manager.js +117 -0
  77. package/dist/lib/sync/backup-manager.js.map +1 -0
  78. package/dist/lib/sync/backup-manager.test.d.ts +2 -0
  79. package/dist/lib/sync/backup-manager.test.d.ts.map +1 -0
  80. package/dist/lib/sync/backup-manager.test.js +155 -0
  81. package/dist/lib/sync/backup-manager.test.js.map +1 -0
  82. package/dist/lib/sync/batch-processor.d.ts +27 -0
  83. package/dist/lib/sync/batch-processor.d.ts.map +1 -0
  84. package/dist/lib/sync/batch-processor.js +46 -0
  85. package/dist/lib/sync/batch-processor.js.map +1 -0
  86. package/dist/lib/sync/batch-processor.test.d.ts +2 -0
  87. package/dist/lib/sync/batch-processor.test.d.ts.map +1 -0
  88. package/dist/lib/sync/batch-processor.test.js +110 -0
  89. package/dist/lib/sync/batch-processor.test.js.map +1 -0
  90. package/dist/lib/sync/category-validator.d.ts +36 -0
  91. package/dist/lib/sync/category-validator.d.ts.map +1 -0
  92. package/dist/lib/sync/category-validator.js +46 -0
  93. package/dist/lib/sync/category-validator.js.map +1 -0
  94. package/dist/lib/sync/category-validator.test.d.ts +2 -0
  95. package/dist/lib/sync/category-validator.test.d.ts.map +1 -0
  96. package/dist/lib/sync/category-validator.test.js +89 -0
  97. package/dist/lib/sync/category-validator.test.js.map +1 -0
  98. package/dist/lib/sync/conflict-reporter.d.ts +57 -0
  99. package/dist/lib/sync/conflict-reporter.d.ts.map +1 -0
  100. package/dist/lib/sync/conflict-reporter.js +81 -0
  101. package/dist/lib/sync/conflict-reporter.js.map +1 -0
  102. package/dist/lib/sync/conflict-reporter.test.d.ts +2 -0
  103. package/dist/lib/sync/conflict-reporter.test.d.ts.map +1 -0
  104. package/dist/lib/sync/conflict-reporter.test.js +132 -0
  105. package/dist/lib/sync/conflict-reporter.test.js.map +1 -0
  106. package/dist/lib/sync/diff-engine.d.ts +28 -0
  107. package/dist/lib/sync/diff-engine.d.ts.map +1 -0
  108. package/dist/lib/sync/diff-engine.js +118 -0
  109. package/dist/lib/sync/diff-engine.js.map +1 -0
  110. package/dist/lib/sync/diff-engine.test.d.ts +2 -0
  111. package/dist/lib/sync/diff-engine.test.d.ts.map +1 -0
  112. package/dist/lib/sync/diff-engine.test.js +133 -0
  113. package/dist/lib/sync/diff-engine.test.js.map +1 -0
  114. package/dist/lib/sync/file-filter.d.ts +40 -0
  115. package/dist/lib/sync/file-filter.d.ts.map +1 -0
  116. package/dist/lib/sync/file-filter.js +171 -0
  117. package/dist/lib/sync/file-filter.js.map +1 -0
  118. package/dist/lib/sync/file-filter.test.d.ts +2 -0
  119. package/dist/lib/sync/file-filter.test.d.ts.map +1 -0
  120. package/dist/lib/sync/file-filter.test.js +179 -0
  121. package/dist/lib/sync/file-filter.test.js.map +1 -0
  122. package/dist/lib/sync/hash-cache.d.ts +34 -0
  123. package/dist/lib/sync/hash-cache.d.ts.map +1 -0
  124. package/dist/lib/sync/hash-cache.js +51 -0
  125. package/dist/lib/sync/hash-cache.js.map +1 -0
  126. package/dist/lib/sync/hash-cache.test.d.ts +2 -0
  127. package/dist/lib/sync/hash-cache.test.d.ts.map +1 -0
  128. package/dist/lib/sync/hash-cache.test.js +110 -0
  129. package/dist/lib/sync/hash-cache.test.js.map +1 -0
  130. package/dist/lib/sync/integration.test.d.ts +2 -0
  131. package/dist/lib/sync/integration.test.d.ts.map +1 -0
  132. package/dist/lib/sync/integration.test.js +317 -0
  133. package/dist/lib/sync/integration.test.js.map +1 -0
  134. package/dist/lib/sync/marker-processor.d.ts +54 -0
  135. package/dist/lib/sync/marker-processor.d.ts.map +1 -0
  136. package/dist/lib/sync/marker-processor.js +208 -0
  137. package/dist/lib/sync/marker-processor.js.map +1 -0
  138. package/dist/lib/sync/marker-processor.test.d.ts +2 -0
  139. package/dist/lib/sync/marker-processor.test.d.ts.map +1 -0
  140. package/dist/lib/sync/marker-processor.test.js +245 -0
  141. package/dist/lib/sync/marker-processor.test.js.map +1 -0
  142. package/dist/lib/sync/metadata-manager.d.ts +46 -0
  143. package/dist/lib/sync/metadata-manager.d.ts.map +1 -0
  144. package/dist/lib/sync/metadata-manager.js +129 -0
  145. package/dist/lib/sync/metadata-manager.js.map +1 -0
  146. package/dist/lib/sync/metadata-manager.test.d.ts +2 -0
  147. package/dist/lib/sync/metadata-manager.test.d.ts.map +1 -0
  148. package/dist/lib/sync/metadata-manager.test.js +137 -0
  149. package/dist/lib/sync/metadata-manager.test.js.map +1 -0
  150. package/dist/lib/sync/performance.test.d.ts +2 -0
  151. package/dist/lib/sync/performance.test.d.ts.map +1 -0
  152. package/dist/lib/sync/performance.test.js +126 -0
  153. package/dist/lib/sync/performance.test.js.map +1 -0
  154. package/dist/types/index.d.ts +59 -0
  155. package/dist/types/index.d.ts.map +1 -0
  156. package/dist/types/index.js +2 -0
  157. package/dist/types/index.js.map +1 -0
  158. package/dist/types/preset-update.d.ts +106 -0
  159. package/dist/types/preset-update.d.ts.map +1 -0
  160. package/dist/types/preset-update.js +5 -0
  161. package/dist/types/preset-update.js.map +1 -0
  162. package/dist/types/sync.d.ts +169 -0
  163. package/dist/types/sync.d.ts.map +1 -0
  164. package/dist/types/sync.js +19 -0
  165. package/dist/types/sync.js.map +1 -0
  166. package/package.json +72 -0
  167. package/presets/minimal/.claude/agents/einja/docs/docs-updater.md +161 -0
  168. package/presets/minimal/.claude/agents/einja/frontend/design-engineer.md +685 -0
  169. package/presets/minimal/.claude/agents/einja/frontend/frontend-architect.md +747 -0
  170. package/presets/minimal/.claude/agents/einja/frontend/frontend-coder.md +441 -0
  171. package/presets/minimal/.claude/agents/einja/git/conflict-resolver.md +148 -0
  172. package/presets/minimal/.claude/agents/einja/specs/spec-design-generator.md +462 -0
  173. package/presets/minimal/.claude/agents/einja/specs/spec-qa-generator.md +466 -0
  174. package/presets/minimal/.claude/agents/einja/specs/spec-requirements-generator.md +416 -0
  175. package/presets/minimal/.claude/agents/einja/specs/spec-tasks-generator.md +608 -0
  176. package/presets/minimal/.claude/agents/einja/task/task-committer.md +82 -0
  177. package/presets/minimal/.claude/agents/einja/task/task-executer.md +352 -0
  178. package/presets/minimal/.claude/agents/einja/task/task-modification-analyzer.md +369 -0
  179. package/presets/minimal/.claude/agents/einja/task/task-qa.md +74 -0
  180. package/presets/minimal/.claude/agents/einja/task/task-reviewer.md +169 -0
  181. package/presets/minimal/.claude/commands/einja/frontend-implement.md +322 -0
  182. package/presets/minimal/.claude/commands/einja/spec-create.md +254 -0
  183. package/presets/minimal/.claude/commands/einja/start-dev.md +98 -0
  184. package/presets/minimal/.claude/commands/einja/sync-cursor-commands.md +203 -0
  185. package/presets/minimal/.claude/commands/einja/task-exec.md +390 -0
  186. package/presets/minimal/.claude/commands/einja/update-docs-by-task-specs.md +448 -0
  187. package/presets/minimal/.claude/hooks/einja/biome-format.sh +49 -0
  188. package/presets/minimal/.claude/hooks/einja/design-doc-check.sh +61 -0
  189. package/presets/minimal/.claude/hooks/einja/detect-secrets.sh +62 -0
  190. package/presets/minimal/.claude/hooks/einja/large-file-warning.sh +42 -0
  191. package/presets/minimal/.claude/hooks/einja/playwright-resize.sh +36 -0
  192. package/presets/minimal/.claude/hooks/einja/typecheck.sh +37 -0
  193. package/presets/minimal/.claude/hooks/einja/unset-volta-recursion.sh +32 -0
  194. package/presets/minimal/.claude/hooks/einja/validate-git-commit.sh +239 -0
  195. package/presets/minimal/.claude/hooks/einja/warn-index-ts.sh +34 -0
  196. package/presets/minimal/.claude/hooks/einja/warn-relative-import.sh +48 -0
  197. package/presets/minimal/.claude/settings.json +174 -0
  198. package/presets/minimal/.claude/skills/einja/api-development/SKILL.md +14 -0
  199. package/presets/minimal/.claude/skills/einja/backend-architecture/SKILL.md +14 -0
  200. package/presets/minimal/.claude/skills/einja/coding-standards/SKILL.md +120 -0
  201. package/presets/minimal/.claude/skills/einja/coding-standards/reference/naming-conventions.md +107 -0
  202. package/presets/minimal/.claude/skills/einja/coding-standards/reference/prohibited-patterns.md +169 -0
  203. package/presets/minimal/.claude/skills/einja/coding-standards/reference/typescript-rules.md +247 -0
  204. package/presets/minimal/.claude/skills/einja/component-design/SKILL.md +109 -0
  205. package/presets/minimal/.claude/skills/einja/component-design/reference/directory-structure.md +117 -0
  206. package/presets/minimal/.claude/skills/einja/component-design/reference/props-patterns.md +159 -0
  207. package/presets/minimal/.claude/skills/einja/component-design/reference/styling-guide.md +200 -0
  208. package/presets/minimal/.claude/skills/einja/conflict-resolver/SKILL.md +190 -0
  209. package/presets/minimal/.claude/skills/einja/frontend-development/SKILL.md +14 -0
  210. package/presets/minimal/.claude/skills/einja/general-context-loader/SKILL.md +254 -0
  211. package/presets/minimal/.claude/skills/einja/output-format/SKILL.md +137 -0
  212. package/presets/minimal/.claude/skills/einja/spec-context-loader/SKILL.md +177 -0
  213. package/presets/minimal/.claude/skills/einja/task-commit/SKILL.md +269 -0
  214. package/presets/minimal/.claude/skills/einja/task-qa/SKILL.md +306 -0
  215. package/presets/minimal/.claude/skills/einja/task-qa/reference/failure-patterns.md +69 -0
  216. package/presets/minimal/.claude/skills/einja/task-qa/reference/troubleshooting.md +65 -0
  217. package/presets/minimal/.claude/skills/einja/task-qa/reference/usage-patterns.md +52 -0
  218. package/presets/minimal/.claude/skills/einja/task-qa/templates/qa-test-template.md +128 -0
  219. package/presets/minimal/preset.yaml +111 -0
  220. package/presets/minimal/symlinks.json +45 -0
  221. package/scaffolds/.mcp.json +45 -0
  222. package/scaffolds/CLAUDE.md.template +318 -0
  223. package/scaffolds/steering/README.md +170 -0
  224. package/scaffolds/steering/acceptance-criteria-and-qa-guide.md +415 -0
  225. package/scaffolds/steering/architecture.md +481 -0
  226. package/scaffolds/steering/branch-strategy.md +362 -0
  227. package/scaffolds/steering/commit-rules.md +217 -0
  228. package/scaffolds/steering/db-schema-design.md +609 -0
  229. package/scaffolds/steering/development/api-development.md +783 -0
  230. package/scaffolds/steering/development/backend-architecture.md +731 -0
  231. package/scaffolds/steering/development/frontend-development.md +1537 -0
  232. package/scaffolds/steering/development/review-guidelines.md +365 -0
  233. package/scaffolds/steering/development/testing-strategy.md +819 -0
  234. package/scaffolds/steering/development-workflow.md +429 -0
  235. package/scaffolds/steering/infrastructure/deployment.md +277 -0
  236. package/scaffolds/steering/infrastructure/environment-variables.md +298 -0
  237. package/scaffolds/steering/product.md +540 -0
  238. package/scaffolds/steering/task-management.md +367 -0
  239. package/templates/README.md +159 -0
  240. package/templates/design-simple.md.template +172 -0
  241. package/templates/design.md.template +327 -0
  242. package/templates/qa-test.md.template +125 -0
  243. package/templates/requirements.md.template +254 -0
@@ -0,0 +1,52 @@
1
+ import fs from "fs-extra";
2
+ import path from "node:path";
3
+ import yaml from "js-yaml";
4
+ import { getPresetPath, getPresetsPath } from "./file-system.js";
5
+ /**
6
+ * プリセット設定を読み込む
7
+ */
8
+ export async function loadPreset(presetName) {
9
+ const presetPath = getPresetPath(presetName);
10
+ const configPath = path.join(presetPath, "preset.yaml");
11
+ if (!await fs.pathExists(configPath)) {
12
+ throw new Error(`プリセット "${presetName}" が見つかりません: ${configPath}`);
13
+ }
14
+ const content = await fs.readFile(configPath, "utf-8");
15
+ const config = yaml.load(content);
16
+ return {
17
+ name: presetName,
18
+ displayName: config.displayName,
19
+ description: config.description,
20
+ config,
21
+ };
22
+ }
23
+ /**
24
+ * 全プリセット情報を取得
25
+ */
26
+ export async function getAllPresets() {
27
+ const presetsPath = getPresetsPath();
28
+ if (!await fs.pathExists(presetsPath)) {
29
+ return [];
30
+ }
31
+ const entries = await fs.readdir(presetsPath, { withFileTypes: true });
32
+ const presetDirs = entries.filter((entry) => entry.isDirectory());
33
+ const presets = [];
34
+ for (const dir of presetDirs) {
35
+ try {
36
+ const preset = await loadPreset(dir.name);
37
+ presets.push(preset);
38
+ }
39
+ catch (_a) {
40
+ // preset.yaml がないディレクトリはスキップ
41
+ }
42
+ }
43
+ return presets;
44
+ }
45
+ /**
46
+ * プリセットが存在するか確認
47
+ */
48
+ export async function presetExists(presetName) {
49
+ const configPath = path.join(getPresetPath(presetName), "preset.yaml");
50
+ return fs.pathExists(configPath);
51
+ }
52
+ //# sourceMappingURL=preset.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"preset.js","sourceRoot":"","sources":["../../src/lib/preset.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,UAAU,CAAC;AAC1B,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,IAAI,MAAM,SAAS,CAAC;AAE3B,OAAO,EAAE,aAAa,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAEjE;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,UAAU,CAAC,UAAkB;IAClD,MAAM,UAAU,GAAG,aAAa,CAAC,UAAU,CAAC,CAAC;IAC7C,MAAM,UAAU,GAAG,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,aAAa,CAAC,CAAC;IAExD,IAAI,CAAC,MAAM,EAAE,CAAC,UAAU,CAAC,UAAU,CAAC,EAAE,CAAC;QACtC,MAAM,IAAI,KAAK,CAAC,UAAU,UAAU,eAAe,UAAU,EAAE,CAAC,CAAC;IAClE,CAAC;IAED,MAAM,OAAO,GAAG,MAAM,EAAE,CAAC,QAAQ,CAAC,UAAU,EAAE,OAAO,CAAC,CAAC;IACvD,MAAM,MAAM,GAAG,IAAI,CAAC,IAAI,CAAC,OAAO,CAAiB,CAAC;IAElD,OAAO;QACN,IAAI,EAAE,UAAU;QAChB,WAAW,EAAE,MAAM,CAAC,WAAW;QAC/B,WAAW,EAAE,MAAM,CAAC,WAAW;QAC/B,MAAM;KACN,CAAC;AACH,CAAC;AAED;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,aAAa;IAClC,MAAM,WAAW,GAAG,cAAc,EAAE,CAAC;IAErC,IAAI,CAAC,MAAM,EAAE,CAAC,UAAU,CAAC,WAAW,CAAC,EAAE,CAAC;QACvC,OAAO,EAAE,CAAC;IACX,CAAC;IAED,MAAM,OAAO,GAAG,MAAM,EAAE,CAAC,OAAO,CAAC,WAAW,EAAE,EAAE,aAAa,EAAE,IAAI,EAAE,CAAC,CAAC;IACvE,MAAM,UAAU,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,WAAW,EAAE,CAAC,CAAC;IAElE,MAAM,OAAO,GAAa,EAAE,CAAC;IAC7B,KAAK,MAAM,GAAG,IAAI,UAAU,EAAE,CAAC;QAC9B,IAAI,CAAC;YACJ,MAAM,MAAM,GAAG,MAAM,UAAU,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;YAC1C,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QACtB,CAAC;QAAC,WAAM,CAAC;YACR,6BAA6B;QAC9B,CAAC;IACF,CAAC;IAED,OAAO,OAAO,CAAC;AAChB,CAAC;AAED;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,YAAY,CAAC,UAAkB;IACpD,MAAM,UAAU,GAAG,IAAI,CAAC,IAAI,CAAC,aAAa,CAAC,UAAU,CAAC,EAAE,aAAa,CAAC,CAAC;IACvE,OAAO,EAAE,CAAC,UAAU,CAAC,UAAU,CAAC,CAAC;AAClC,CAAC"}
@@ -0,0 +1,50 @@
1
+ /**
2
+ * バックアップ管理クラス
3
+ * 同期前のファイルバックアップとリストア機能を提供
4
+ */
5
+ export declare class BackupManager {
6
+ private projectRoot;
7
+ private backupDir;
8
+ constructor(projectRoot: string);
9
+ /**
10
+ * バックアップディレクトリを作成する
11
+ */
12
+ ensureBackupDir(): Promise<void>;
13
+ /**
14
+ * ファイルをバックアップする
15
+ * @param filePath - プロジェクトルートからの相対パス
16
+ * @returns バックアップファイルのパス
17
+ */
18
+ backupFile(filePath: string): Promise<string>;
19
+ /**
20
+ * 複数のファイルをバックアップする
21
+ * @param filePaths - バックアップするファイルパスのリスト
22
+ * @returns バックアップファイルパスのマップ
23
+ */
24
+ backupFiles(filePaths: string[]): Promise<Map<string, string>>;
25
+ /**
26
+ * バックアップファイルをリストアする
27
+ * @param backupPath - バックアップファイルのパス
28
+ * @param targetPath - リストア先のパス
29
+ */
30
+ restoreFile(backupPath: string, targetPath: string): Promise<void>;
31
+ /**
32
+ * すべてのバックアップファイルをリストアする
33
+ * @param backupMap - backupFilesで取得したマップ
34
+ */
35
+ restoreFiles(backupMap: Map<string, string>): Promise<void>;
36
+ /**
37
+ * 古いバックアップファイルをクリーンアップする
38
+ * @param maxAge - 保持する最大日数(デフォルト: 7日)
39
+ */
40
+ cleanupOldBackups(maxAge?: number): Promise<number>;
41
+ /**
42
+ * すべてのバックアップファイルを削除する
43
+ */
44
+ clearAllBackups(): Promise<void>;
45
+ /**
46
+ * バックアップディレクトリのパスを取得する
47
+ */
48
+ getBackupDir(): string;
49
+ }
50
+ //# sourceMappingURL=backup-manager.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"backup-manager.d.ts","sourceRoot":"","sources":["../../../src/lib/sync/backup-manager.ts"],"names":[],"mappings":"AAGA;;;GAGG;AACH,qBAAa,aAAa;IACzB,OAAO,CAAC,WAAW,CAAS;IAC5B,OAAO,CAAC,SAAS,CAAS;gBAEd,WAAW,EAAE,MAAM;IAK/B;;OAEG;IACG,eAAe,IAAI,OAAO,CAAC,IAAI,CAAC;IAItC;;;;OAIG;IACG,UAAU,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAkBnD;;;;OAIG;IACG,WAAW,CAChB,SAAS,EAAE,MAAM,EAAE,GACjB,OAAO,CAAC,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAmB/B;;;;OAIG;IACG,WAAW,CAAC,UAAU,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IASxE;;;OAGG;IACG,YAAY,CAAC,SAAS,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC;IAMjE;;;OAGG;IACG,iBAAiB,CAAC,MAAM,SAAI,GAAG,OAAO,CAAC,MAAM,CAAC;IAuBpD;;OAEG;IACG,eAAe,IAAI,OAAO,CAAC,IAAI,CAAC;IAMtC;;OAEG;IACH,YAAY,IAAI,MAAM;CAGtB"}
@@ -0,0 +1,117 @@
1
+ import fs from "fs-extra";
2
+ import path from "node:path";
3
+ /**
4
+ * バックアップ管理クラス
5
+ * 同期前のファイルバックアップとリストア機能を提供
6
+ */
7
+ export class BackupManager {
8
+ constructor(projectRoot) {
9
+ this.projectRoot = projectRoot;
10
+ this.backupDir = path.join(projectRoot, ".einja-sync-backups");
11
+ }
12
+ /**
13
+ * バックアップディレクトリを作成する
14
+ */
15
+ async ensureBackupDir() {
16
+ await fs.ensureDir(this.backupDir);
17
+ }
18
+ /**
19
+ * ファイルをバックアップする
20
+ * @param filePath - プロジェクトルートからの相対パス
21
+ * @returns バックアップファイルのパス
22
+ */
23
+ async backupFile(filePath) {
24
+ const sourcePath = path.join(this.projectRoot, filePath);
25
+ if (!(await fs.pathExists(sourcePath))) {
26
+ throw new Error(`バックアップ対象ファイルが存在しません: ${filePath}`);
27
+ }
28
+ await this.ensureBackupDir();
29
+ // バックアップファイル名:タイムスタンプ付き
30
+ const timestamp = new Date().toISOString().replace(/[:.]/g, "-");
31
+ const fileName = path.basename(filePath);
32
+ const backupFileName = `${fileName}.${timestamp}.bak`;
33
+ const backupPath = path.join(this.backupDir, backupFileName);
34
+ await fs.copy(sourcePath, backupPath);
35
+ return backupPath;
36
+ }
37
+ /**
38
+ * 複数のファイルをバックアップする
39
+ * @param filePaths - バックアップするファイルパスのリスト
40
+ * @returns バックアップファイルパスのマップ
41
+ */
42
+ async backupFiles(filePaths) {
43
+ const backupMap = new Map();
44
+ for (const filePath of filePaths) {
45
+ try {
46
+ const backupPath = await this.backupFile(filePath);
47
+ backupMap.set(filePath, backupPath);
48
+ }
49
+ catch (error) {
50
+ // ファイルが存在しない場合はスキップ
51
+ if (error instanceof Error && error.message.includes("存在しません")) {
52
+ continue;
53
+ }
54
+ throw error;
55
+ }
56
+ }
57
+ return backupMap;
58
+ }
59
+ /**
60
+ * バックアップファイルをリストアする
61
+ * @param backupPath - バックアップファイルのパス
62
+ * @param targetPath - リストア先のパス
63
+ */
64
+ async restoreFile(backupPath, targetPath) {
65
+ if (!(await fs.pathExists(backupPath))) {
66
+ throw new Error(`バックアップファイルが存在しません: ${backupPath}`);
67
+ }
68
+ const targetFullPath = path.join(this.projectRoot, targetPath);
69
+ await fs.copy(backupPath, targetFullPath, { overwrite: true });
70
+ }
71
+ /**
72
+ * すべてのバックアップファイルをリストアする
73
+ * @param backupMap - backupFilesで取得したマップ
74
+ */
75
+ async restoreFiles(backupMap) {
76
+ for (const [filePath, backupPath] of backupMap.entries()) {
77
+ await this.restoreFile(backupPath, filePath);
78
+ }
79
+ }
80
+ /**
81
+ * 古いバックアップファイルをクリーンアップする
82
+ * @param maxAge - 保持する最大日数(デフォルト: 7日)
83
+ */
84
+ async cleanupOldBackups(maxAge = 7) {
85
+ if (!(await fs.pathExists(this.backupDir))) {
86
+ return 0;
87
+ }
88
+ const files = await fs.readdir(this.backupDir);
89
+ const now = Date.now();
90
+ const maxAgeMs = maxAge * 24 * 60 * 60 * 1000;
91
+ let deletedCount = 0;
92
+ for (const file of files) {
93
+ const filePath = path.join(this.backupDir, file);
94
+ const stat = await fs.stat(filePath);
95
+ if (now - stat.mtime.getTime() > maxAgeMs) {
96
+ await fs.remove(filePath);
97
+ deletedCount++;
98
+ }
99
+ }
100
+ return deletedCount;
101
+ }
102
+ /**
103
+ * すべてのバックアップファイルを削除する
104
+ */
105
+ async clearAllBackups() {
106
+ if (await fs.pathExists(this.backupDir)) {
107
+ await fs.remove(this.backupDir);
108
+ }
109
+ }
110
+ /**
111
+ * バックアップディレクトリのパスを取得する
112
+ */
113
+ getBackupDir() {
114
+ return this.backupDir;
115
+ }
116
+ }
117
+ //# sourceMappingURL=backup-manager.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"backup-manager.js","sourceRoot":"","sources":["../../../src/lib/sync/backup-manager.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=backup-manager.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"backup-manager.test.d.ts","sourceRoot":"","sources":["../../../src/lib/sync/backup-manager.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,155 @@
1
+ import { beforeEach, describe, expect, it } from "vitest";
2
+ import fs from "fs-extra";
3
+ import os from "node:os";
4
+ import path from "node:path";
5
+ import { BackupManager } from "./backup-manager.js";
6
+ describe("BackupManager", () => {
7
+ let tempDir;
8
+ let manager;
9
+ beforeEach(async () => {
10
+ // テスト用一時ディレクトリを作成
11
+ tempDir = await fs.mkdtemp(path.join(os.tmpdir(), "backup-test-"));
12
+ manager = new BackupManager(tempDir);
13
+ });
14
+ describe("backupFile", () => {
15
+ it("ファイルをバックアップディレクトリにコピーする", async () => {
16
+ const testFile = "test.txt";
17
+ const testContent = "Test content";
18
+ const testFilePath = path.join(tempDir, testFile);
19
+ // テストファイルを作成
20
+ await fs.writeFile(testFilePath, testContent, "utf-8");
21
+ // バックアップを実行
22
+ const backupPath = await manager.backupFile(testFile);
23
+ // バックアップファイルが存在することを確認
24
+ expect(await fs.pathExists(backupPath)).toBe(true);
25
+ // バックアップの内容が元のファイルと一致することを確認
26
+ const backupContent = await fs.readFile(backupPath, "utf-8");
27
+ expect(backupContent).toBe(testContent);
28
+ });
29
+ it("存在しないファイルをバックアップしようとした場合、エラーをスローする", async () => {
30
+ await expect(manager.backupFile("nonexistent.txt")).rejects.toThrow("バックアップ対象ファイルが存在しません");
31
+ });
32
+ });
33
+ describe("backupFiles", () => {
34
+ it("複数のファイルをバックアップする", async () => {
35
+ const files = ["file1.txt", "file2.txt"];
36
+ const content1 = "Content 1";
37
+ const content2 = "Content 2";
38
+ // テストファイルを作成
39
+ await fs.writeFile(path.join(tempDir, files[0]), content1, "utf-8");
40
+ await fs.writeFile(path.join(tempDir, files[1]), content2, "utf-8");
41
+ // バックアップを実行
42
+ const backupMap = await manager.backupFiles(files);
43
+ // 2つのファイルがバックアップされたことを確認
44
+ expect(backupMap.size).toBe(2);
45
+ expect(backupMap.has(files[0])).toBe(true);
46
+ expect(backupMap.has(files[1])).toBe(true);
47
+ // バックアップファイルの内容を確認
48
+ const backup1Content = await fs.readFile(backupMap.get(files[0]), "utf-8");
49
+ const backup2Content = await fs.readFile(backupMap.get(files[1]), "utf-8");
50
+ expect(backup1Content).toBe(content1);
51
+ expect(backup2Content).toBe(content2);
52
+ });
53
+ it("存在しないファイルはスキップする", async () => {
54
+ const files = ["exists.txt", "nonexistent.txt"];
55
+ await fs.writeFile(path.join(tempDir, files[0]), "Content", "utf-8");
56
+ // バックアップを実行(エラーにならず、存在するファイルのみバックアップ)
57
+ const backupMap = await manager.backupFiles(files);
58
+ expect(backupMap.size).toBe(1);
59
+ expect(backupMap.has(files[0])).toBe(true);
60
+ expect(backupMap.has(files[1])).toBe(false);
61
+ });
62
+ });
63
+ describe("restoreFile", () => {
64
+ it("バックアップファイルをリストアする", async () => {
65
+ const originalFile = "test.txt";
66
+ const originalContent = "Original content";
67
+ const originalPath = path.join(tempDir, originalFile);
68
+ // 元のファイルを作成してバックアップ
69
+ await fs.writeFile(originalPath, originalContent, "utf-8");
70
+ const backupPath = await manager.backupFile(originalFile);
71
+ // 元のファイルを変更
72
+ await fs.writeFile(originalPath, "Modified content", "utf-8");
73
+ // リストアを実行
74
+ await manager.restoreFile(backupPath, originalFile);
75
+ // 元の内容に戻っていることを確認
76
+ const restoredContent = await fs.readFile(originalPath, "utf-8");
77
+ expect(restoredContent).toBe(originalContent);
78
+ });
79
+ it("バックアップファイルが存在しない場合、エラーをスローする", async () => {
80
+ await expect(manager.restoreFile("/nonexistent/backup.txt", "test.txt")).rejects.toThrow("バックアップファイルが存在しません");
81
+ });
82
+ });
83
+ describe("restoreFiles", () => {
84
+ it("複数のバックアップファイルをリストアする", async () => {
85
+ const files = ["file1.txt", "file2.txt"];
86
+ const originalContents = ["Content 1", "Content 2"];
87
+ // 元のファイルを作成してバックアップ
88
+ await fs.writeFile(path.join(tempDir, files[0]), originalContents[0], "utf-8");
89
+ await fs.writeFile(path.join(tempDir, files[1]), originalContents[1], "utf-8");
90
+ const backupMap = await manager.backupFiles(files);
91
+ // 元のファイルを変更
92
+ await fs.writeFile(path.join(tempDir, files[0]), "Modified 1", "utf-8");
93
+ await fs.writeFile(path.join(tempDir, files[1]), "Modified 2", "utf-8");
94
+ // リストアを実行
95
+ await manager.restoreFiles(backupMap);
96
+ // 両方のファイルが元の内容に戻っていることを確認
97
+ const restored1 = await fs.readFile(path.join(tempDir, files[0]), "utf-8");
98
+ const restored2 = await fs.readFile(path.join(tempDir, files[1]), "utf-8");
99
+ expect(restored1).toBe(originalContents[0]);
100
+ expect(restored2).toBe(originalContents[1]);
101
+ });
102
+ });
103
+ describe("cleanupOldBackups", () => {
104
+ it("古いバックアップファイルを削除する", async () => {
105
+ const backupDir = manager.getBackupDir();
106
+ await fs.ensureDir(backupDir);
107
+ // 古いバックアップファイルを作成(8日前)
108
+ const oldBackup = path.join(backupDir, "old-backup.txt");
109
+ await fs.writeFile(oldBackup, "Old backup", "utf-8");
110
+ const oldDate = new Date();
111
+ oldDate.setDate(oldDate.getDate() - 8);
112
+ await fs.utimes(oldBackup, oldDate, oldDate);
113
+ // 新しいバックアップファイルを作成(今日)
114
+ const newBackup = path.join(backupDir, "new-backup.txt");
115
+ await fs.writeFile(newBackup, "New backup", "utf-8");
116
+ // クリーンアップを実行(7日より古いファイルを削除)
117
+ const deletedCount = await manager.cleanupOldBackups(7);
118
+ // 1ファイルが削除されたことを確認
119
+ expect(deletedCount).toBe(1);
120
+ // 古いファイルが削除され、新しいファイルは残っていることを確認
121
+ expect(await fs.pathExists(oldBackup)).toBe(false);
122
+ expect(await fs.pathExists(newBackup)).toBe(true);
123
+ });
124
+ it("バックアップディレクトリが存在しない場合、0を返す", async () => {
125
+ const deletedCount = await manager.cleanupOldBackups(7);
126
+ expect(deletedCount).toBe(0);
127
+ });
128
+ });
129
+ describe("clearAllBackups", () => {
130
+ it("すべてのバックアップファイルを削除する", async () => {
131
+ const backupDir = manager.getBackupDir();
132
+ // バックアップファイルを作成
133
+ const testFile = "test.txt";
134
+ await fs.writeFile(path.join(tempDir, testFile), "Content", "utf-8");
135
+ await manager.backupFile(testFile);
136
+ // バックアップディレクトリが存在することを確認
137
+ expect(await fs.pathExists(backupDir)).toBe(true);
138
+ // すべてのバックアップを削除
139
+ await manager.clearAllBackups();
140
+ // バックアップディレクトリが削除されたことを確認
141
+ expect(await fs.pathExists(backupDir)).toBe(false);
142
+ });
143
+ it("バックアップディレクトリが存在しない場合、エラーにならない", async () => {
144
+ // エラーなく実行できることを確認
145
+ await expect(manager.clearAllBackups()).resolves.toBeUndefined();
146
+ });
147
+ });
148
+ describe("getBackupDir", () => {
149
+ it("バックアップディレクトリのパスを返す", () => {
150
+ const backupDir = manager.getBackupDir();
151
+ expect(backupDir).toBe(path.join(tempDir, ".einja-sync-backups"));
152
+ });
153
+ });
154
+ });
155
+ //# sourceMappingURL=backup-manager.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"backup-manager.test.js","sourceRoot":"","sources":["../../../src/lib/sync/backup-manager.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,27 @@
1
+ /**
2
+ * バッチ処理クラス
3
+ * ファイルの並列処理を制御し、メモリ使用量を抑制する
4
+ */
5
+ export declare class BatchProcessor {
6
+ private batchSize;
7
+ /**
8
+ * @param batchSize バッチサイズ(デフォルト: 10ファイル)
9
+ */
10
+ constructor(batchSize?: number);
11
+ /**
12
+ * アイテムをバッチごとに並列処理する
13
+ * @param items 処理対象のアイテム配列
14
+ * @param processor 各アイテムを処理する関数
15
+ * @returns 処理結果の配列
16
+ */
17
+ processBatch<T, R>(items: T[], processor: (item: T) => Promise<R>): Promise<R[]>;
18
+ /**
19
+ * バッチサイズを取得する
20
+ */
21
+ getBatchSize(): number;
22
+ /**
23
+ * バッチサイズを設定する
24
+ */
25
+ setBatchSize(size: number): void;
26
+ }
27
+ //# sourceMappingURL=batch-processor.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"batch-processor.d.ts","sourceRoot":"","sources":["../../../src/lib/sync/batch-processor.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,qBAAa,cAAc;IAC1B,OAAO,CAAC,SAAS,CAAS;IAE1B;;OAEG;gBACS,SAAS,SAAK;IAI1B;;;;;OAKG;IACG,YAAY,CAAC,CAAC,EAAE,CAAC,EACtB,KAAK,EAAE,CAAC,EAAE,EACV,SAAS,EAAE,CAAC,IAAI,EAAE,CAAC,KAAK,OAAO,CAAC,CAAC,CAAC,GAChC,OAAO,CAAC,CAAC,EAAE,CAAC;IAiBf;;OAEG;IACH,YAAY,IAAI,MAAM;IAItB;;OAEG;IACH,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI;CAMhC"}
@@ -0,0 +1,46 @@
1
+ /**
2
+ * バッチ処理クラス
3
+ * ファイルの並列処理を制御し、メモリ使用量を抑制する
4
+ */
5
+ export class BatchProcessor {
6
+ /**
7
+ * @param batchSize バッチサイズ(デフォルト: 10ファイル)
8
+ */
9
+ constructor(batchSize = 10) {
10
+ this.batchSize = batchSize;
11
+ }
12
+ /**
13
+ * アイテムをバッチごとに並列処理する
14
+ * @param items 処理対象のアイテム配列
15
+ * @param processor 各アイテムを処理する関数
16
+ * @returns 処理結果の配列
17
+ */
18
+ async processBatch(items, processor) {
19
+ const results = [];
20
+ // アイテムをバッチに分割
21
+ for (let i = 0; i < items.length; i += this.batchSize) {
22
+ const batch = items.slice(i, i + this.batchSize);
23
+ // バッチ内のアイテムを並列処理
24
+ const batchResults = await Promise.all(batch.map((item) => processor(item)));
25
+ // 結果を収集
26
+ results.push(...batchResults);
27
+ }
28
+ return results;
29
+ }
30
+ /**
31
+ * バッチサイズを取得する
32
+ */
33
+ getBatchSize() {
34
+ return this.batchSize;
35
+ }
36
+ /**
37
+ * バッチサイズを設定する
38
+ */
39
+ setBatchSize(size) {
40
+ if (size <= 0) {
41
+ throw new Error("バッチサイズは1以上である必要があります");
42
+ }
43
+ this.batchSize = size;
44
+ }
45
+ }
46
+ //# sourceMappingURL=batch-processor.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"batch-processor.js","sourceRoot":"","sources":["../../../src/lib/sync/batch-processor.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,MAAM,OAAO,cAAc;IAG1B;;OAEG;IACH,YAAY,SAAS,GAAG,EAAE;QACzB,IAAI,CAAC,SAAS,GAAG,SAAS,CAAC;IAC5B,CAAC;IAED;;;;;OAKG;IACH,KAAK,CAAC,YAAY,CACjB,KAAU,EACV,SAAkC;QAElC,MAAM,OAAO,GAAQ,EAAE,CAAC;QAExB,cAAc;QACd,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC,IAAI,IAAI,CAAC,SAAS,EAAE,CAAC;YACvD,MAAM,KAAK,GAAG,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,SAAS,CAAC,CAAC;YAEjD,iBAAiB;YACjB,MAAM,YAAY,GAAG,MAAM,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;YAE7E,QAAQ;YACR,OAAO,CAAC,IAAI,CAAC,GAAG,YAAY,CAAC,CAAC;QAC/B,CAAC;QAED,OAAO,OAAO,CAAC;IAChB,CAAC;IAED;;OAEG;IACH,YAAY;QACX,OAAO,IAAI,CAAC,SAAS,CAAC;IACvB,CAAC;IAED;;OAEG;IACH,YAAY,CAAC,IAAY;QACxB,IAAI,IAAI,IAAI,CAAC,EAAE,CAAC;YACf,MAAM,IAAI,KAAK,CAAC,sBAAsB,CAAC,CAAC;QACzC,CAAC;QACD,IAAI,CAAC,SAAS,GAAG,IAAI,CAAC;IACvB,CAAC;CACD"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=batch-processor.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"batch-processor.test.d.ts","sourceRoot":"","sources":["../../../src/lib/sync/batch-processor.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,110 @@
1
+ import { describe, expect, it, vi } from "vitest";
2
+ import { BatchProcessor } from "./batch-processor.js";
3
+ describe("BatchProcessor", () => {
4
+ describe("processBatchメソッド", () => {
5
+ it("10ファイル単位でバッチ処理を実行すること", async () => {
6
+ const processor = new BatchProcessor(10);
7
+ const items = Array.from({ length: 25 }, (_, i) => i); // 25個のアイテム
8
+ const mockFn = vi.fn(async (item) => item * 2);
9
+ const results = await processor.processBatch(items, mockFn);
10
+ // 全アイテムが処理されること
11
+ expect(results).toHaveLength(25);
12
+ expect(results).toEqual(items.map((i) => i * 2));
13
+ expect(mockFn).toHaveBeenCalledTimes(25);
14
+ });
15
+ it("空の配列を渡した場合、空の結果を返すこと", async () => {
16
+ const processor = new BatchProcessor(10);
17
+ const items = [];
18
+ const mockFn = vi.fn(async (item) => item);
19
+ const results = await processor.processBatch(items, mockFn);
20
+ expect(results).toEqual([]);
21
+ expect(mockFn).not.toHaveBeenCalled();
22
+ });
23
+ it("アイテム数がバッチサイズより少ない場合、1バッチで処理されること", async () => {
24
+ const processor = new BatchProcessor(10);
25
+ const items = [1, 2, 3]; // 3個のアイテム
26
+ const mockFn = vi.fn(async (item) => item * 2);
27
+ const results = await processor.processBatch(items, mockFn);
28
+ expect(results).toEqual([2, 4, 6]);
29
+ expect(mockFn).toHaveBeenCalledTimes(3);
30
+ });
31
+ it("バッチサイズちょうどのアイテム数の場合、1バッチで処理されること", async () => {
32
+ const processor = new BatchProcessor(10);
33
+ const items = Array.from({ length: 10 }, (_, i) => i);
34
+ const mockFn = vi.fn(async (item) => item);
35
+ const results = await processor.processBatch(items, mockFn);
36
+ expect(results).toHaveLength(10);
37
+ expect(mockFn).toHaveBeenCalledTimes(10);
38
+ });
39
+ it("100ファイルの処理を並列化できること", async () => {
40
+ const processor = new BatchProcessor(10);
41
+ const items = Array.from({ length: 100 }, (_, i) => i);
42
+ const mockFn = vi.fn(async (item) => {
43
+ // 簡易的な非同期処理をシミュレート
44
+ await new Promise((resolve) => setTimeout(resolve, 1));
45
+ return item * 2;
46
+ });
47
+ const startTime = Date.now();
48
+ const results = await processor.processBatch(items, mockFn);
49
+ const endTime = Date.now();
50
+ expect(results).toHaveLength(100);
51
+ expect(mockFn).toHaveBeenCalledTimes(100);
52
+ // 並列処理により処理時間が短縮されることを確認(目安: 100ms未満)
53
+ // バッチサイズ10で100ファイル = 10バッチ
54
+ // 各バッチは並列実行されるため、10バッチ × 1ms = 約10ms(実際はオーバーヘッドがあるので100ms以内)
55
+ expect(endTime - startTime).toBeLessThan(100);
56
+ });
57
+ it("エラーが発生した場合、Promiseがrejectされること", async () => {
58
+ const processor = new BatchProcessor(10);
59
+ const items = [1, 2, 3];
60
+ const mockFn = vi.fn(async (item) => {
61
+ if (item === 2) {
62
+ throw new Error("処理エラー");
63
+ }
64
+ return item;
65
+ });
66
+ await expect(processor.processBatch(items, mockFn)).rejects.toThrow("処理エラー");
67
+ });
68
+ });
69
+ describe("getBatchSizeメソッド", () => {
70
+ it("設定されたバッチサイズを返すこと", () => {
71
+ const processor = new BatchProcessor(10);
72
+ expect(processor.getBatchSize()).toBe(10);
73
+ });
74
+ it("カスタムバッチサイズを設定できること", () => {
75
+ const processor = new BatchProcessor(20);
76
+ expect(processor.getBatchSize()).toBe(20);
77
+ });
78
+ });
79
+ describe("setBatchSizeメソッド", () => {
80
+ it("バッチサイズを変更できること", () => {
81
+ const processor = new BatchProcessor(10);
82
+ processor.setBatchSize(20);
83
+ expect(processor.getBatchSize()).toBe(20);
84
+ });
85
+ it("バッチサイズが0以下の場合、エラーを投げること", () => {
86
+ const processor = new BatchProcessor(10);
87
+ expect(() => processor.setBatchSize(0)).toThrow("バッチサイズは1以上である必要があります");
88
+ expect(() => processor.setBatchSize(-1)).toThrow("バッチサイズは1以上である必要があります");
89
+ });
90
+ });
91
+ describe("並列処理の効果検証", () => {
92
+ it("バッチ内のアイテムが並列に処理されること", async () => {
93
+ const processor = new BatchProcessor(3);
94
+ const executionOrder = [];
95
+ const items = [1, 2, 3, 4, 5];
96
+ const mockFn = vi.fn(async (item) => {
97
+ // 非同期処理の開始を記録
98
+ executionOrder.push(item);
99
+ await new Promise((resolve) => setTimeout(resolve, 10));
100
+ return item;
101
+ });
102
+ await processor.processBatch(items, mockFn);
103
+ // バッチ1: 1, 2, 3が並列処理
104
+ // バッチ2: 4, 5が並列処理
105
+ expect(executionOrder.slice(0, 3)).toEqual([1, 2, 3]);
106
+ expect(executionOrder.slice(3)).toEqual([4, 5]);
107
+ });
108
+ });
109
+ });
110
+ //# sourceMappingURL=batch-processor.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"batch-processor.test.js","sourceRoot":"","sources":["../../../src/lib/sync/batch-processor.test.ts"],"names":[],"mappings":"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"}