@sk8metal/michi-cli 0.5.0 → 0.8.0

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 (284) hide show
  1. package/CHANGELOG.md +136 -1
  2. package/README.md +2 -1
  3. package/dist/scripts/config/config-schema.d.ts +35 -0
  4. package/dist/scripts/config/config-schema.d.ts.map +1 -1
  5. package/dist/scripts/config/config-schema.js +56 -0
  6. package/dist/scripts/config/config-schema.js.map +1 -1
  7. package/dist/scripts/confluence-sync.d.ts.map +1 -1
  8. package/dist/scripts/confluence-sync.js +15 -2
  9. package/dist/scripts/confluence-sync.js.map +1 -1
  10. package/dist/scripts/github-actions-client.d.ts +79 -0
  11. package/dist/scripts/github-actions-client.d.ts.map +1 -0
  12. package/dist/scripts/github-actions-client.js +182 -0
  13. package/dist/scripts/github-actions-client.js.map +1 -0
  14. package/dist/scripts/health-check-service.d.ts +46 -0
  15. package/dist/scripts/health-check-service.d.ts.map +1 -0
  16. package/dist/scripts/health-check-service.js +114 -0
  17. package/dist/scripts/health-check-service.js.map +1 -0
  18. package/dist/scripts/markdown-to-confluence.d.ts.map +1 -1
  19. package/dist/scripts/markdown-to-confluence.js +25 -3
  20. package/dist/scripts/markdown-to-confluence.js.map +1 -1
  21. package/dist/scripts/mermaid-converter.d.ts +24 -0
  22. package/dist/scripts/mermaid-converter.d.ts.map +1 -0
  23. package/dist/scripts/mermaid-converter.js +49 -0
  24. package/dist/scripts/mermaid-converter.js.map +1 -0
  25. package/dist/scripts/template/multi-repo-renderer.d.ts +67 -0
  26. package/dist/scripts/template/multi-repo-renderer.d.ts.map +1 -0
  27. package/dist/scripts/template/multi-repo-renderer.js +123 -0
  28. package/dist/scripts/template/multi-repo-renderer.js.map +1 -0
  29. package/dist/scripts/template/renderer.d.ts +4 -0
  30. package/dist/scripts/template/renderer.d.ts.map +1 -1
  31. package/dist/scripts/template/renderer.js.map +1 -1
  32. package/dist/scripts/test-execution-generator.d.ts.map +1 -1
  33. package/dist/scripts/test-execution-generator.js +94 -11
  34. package/dist/scripts/test-execution-generator.js.map +1 -1
  35. package/dist/scripts/test-script-runner.d.ts +33 -0
  36. package/dist/scripts/test-script-runner.d.ts.map +1 -0
  37. package/dist/scripts/test-script-runner.js +77 -0
  38. package/dist/scripts/test-script-runner.js.map +1 -0
  39. package/dist/scripts/utils/config-loader.d.ts +21 -1
  40. package/dist/scripts/utils/config-loader.d.ts.map +1 -1
  41. package/dist/scripts/utils/config-loader.js +149 -3
  42. package/dist/scripts/utils/config-loader.js.map +1 -1
  43. package/dist/scripts/utils/multi-repo-validator.d.ts +30 -0
  44. package/dist/scripts/utils/multi-repo-validator.d.ts.map +1 -0
  45. package/dist/scripts/utils/multi-repo-validator.js +105 -0
  46. package/dist/scripts/utils/multi-repo-validator.js.map +1 -0
  47. package/dist/scripts/utils/spec-archiver.d.ts +38 -0
  48. package/dist/scripts/utils/spec-archiver.d.ts.map +1 -0
  49. package/dist/scripts/utils/spec-archiver.js +210 -0
  50. package/dist/scripts/utils/spec-archiver.js.map +1 -0
  51. package/dist/scripts/utils/spec-updater.d.ts +4 -0
  52. package/dist/scripts/utils/spec-updater.d.ts.map +1 -1
  53. package/dist/scripts/utils/spec-updater.js.map +1 -1
  54. package/dist/src/cli.d.ts.map +1 -1
  55. package/dist/src/cli.js +262 -14
  56. package/dist/src/cli.js.map +1 -1
  57. package/dist/src/commands/multi-repo-add-repo.d.ts +26 -0
  58. package/dist/src/commands/multi-repo-add-repo.d.ts.map +1 -0
  59. package/dist/src/commands/multi-repo-add-repo.js +56 -0
  60. package/dist/src/commands/multi-repo-add-repo.js.map +1 -0
  61. package/dist/src/commands/multi-repo-ci-status.d.ts +46 -0
  62. package/dist/src/commands/multi-repo-ci-status.d.ts.map +1 -0
  63. package/dist/src/commands/multi-repo-ci-status.js +285 -0
  64. package/dist/src/commands/multi-repo-ci-status.js.map +1 -0
  65. package/dist/src/commands/multi-repo-confluence-sync.d.ts +45 -0
  66. package/dist/src/commands/multi-repo-confluence-sync.d.ts.map +1 -0
  67. package/dist/src/commands/multi-repo-confluence-sync.js +135 -0
  68. package/dist/src/commands/multi-repo-confluence-sync.js.map +1 -0
  69. package/dist/src/commands/multi-repo-init.d.ts +26 -0
  70. package/dist/src/commands/multi-repo-init.d.ts.map +1 -0
  71. package/dist/src/commands/multi-repo-init.js +101 -0
  72. package/dist/src/commands/multi-repo-init.js.map +1 -0
  73. package/dist/src/commands/multi-repo-list.d.ts +28 -0
  74. package/dist/src/commands/multi-repo-list.d.ts.map +1 -0
  75. package/dist/src/commands/multi-repo-list.js +38 -0
  76. package/dist/src/commands/multi-repo-list.js.map +1 -0
  77. package/dist/src/commands/multi-repo-test.d.ts +56 -0
  78. package/dist/src/commands/multi-repo-test.d.ts.map +1 -0
  79. package/dist/src/commands/multi-repo-test.js +70 -0
  80. package/dist/src/commands/multi-repo-test.js.map +1 -0
  81. package/dist/src/commands/setup-existing.d.ts.map +1 -1
  82. package/dist/src/commands/setup-existing.js +30 -8
  83. package/dist/src/commands/setup-existing.js.map +1 -1
  84. package/dist/src/commands/spec-archive.d.ts +17 -0
  85. package/dist/src/commands/spec-archive.d.ts.map +1 -0
  86. package/dist/src/commands/spec-archive.js +40 -0
  87. package/dist/src/commands/spec-archive.js.map +1 -0
  88. package/dist/src/commands/spec-list.d.ts +15 -0
  89. package/dist/src/commands/spec-list.d.ts.map +1 -0
  90. package/dist/src/commands/spec-list.js +55 -0
  91. package/dist/src/commands/spec-list.js.map +1 -0
  92. package/docs/user-guide/guides/multi-repo-guide.md +591 -0
  93. package/docs/user-guide/guides/multi-repo-migration-guide.md +516 -0
  94. package/docs/user-guide/reference/multi-repo-api.md +771 -0
  95. package/docs/user-guide/reference/quick-reference.md +22 -37
  96. package/package.json +1 -4
  97. package/scripts/__tests__/config-loader-multi-repo.test.ts +342 -0
  98. package/scripts/__tests__/github-actions-client.test.ts +543 -0
  99. package/scripts/__tests__/health-check-service.test.ts +142 -0
  100. package/scripts/__tests__/markdown-to-confluence.test.ts +262 -0
  101. package/scripts/__tests__/mermaid-converter.test.ts +236 -0
  102. package/scripts/__tests__/multi-repo-config-schema.test.ts +335 -0
  103. package/scripts/__tests__/multi-repo-validator.test.ts +524 -0
  104. package/scripts/__tests__/spec-archiver.test.ts +512 -0
  105. package/scripts/__tests__/test-script-runner.test.ts +217 -0
  106. package/scripts/config/config-schema.ts +64 -0
  107. package/scripts/confluence-sync.ts +16 -2
  108. package/scripts/github-actions-client.ts +258 -0
  109. package/scripts/health-check-service.ts +171 -0
  110. package/scripts/markdown-to-confluence.ts +37 -6
  111. package/scripts/mermaid-converter.ts +56 -0
  112. package/scripts/template/__tests__/multi-repo-renderer.test.ts +261 -0
  113. package/scripts/template/multi-repo-renderer.ts +172 -0
  114. package/scripts/template/renderer.ts +5 -0
  115. package/scripts/test-execution-generator.ts +104 -11
  116. package/scripts/test-script-runner.ts +130 -0
  117. package/scripts/utils/__tests__/config-validator.test.ts +104 -6
  118. package/scripts/utils/__tests__/multi-repo-validator.test.ts +335 -0
  119. package/scripts/utils/config-loader.ts +197 -3
  120. package/scripts/utils/multi-repo-validator.ts +141 -0
  121. package/scripts/utils/spec-archiver.ts +260 -0
  122. package/scripts/utils/spec-updater.ts +4 -0
  123. package/templates/claude/agents/pr-size-monitor/AGENT.md +330 -0
  124. package/templates/claude/commands/michi/spec-impl.md +208 -35
  125. package/templates/claude-agent/agents/doc-reviewer.md +176 -0
  126. package/templates/claude-agent/rules/doc-review-rules.md +98 -0
  127. package/templates/claude-agent/rules/doc-review.md +91 -0
  128. package/templates/multi-repo/docs/ci-status.md +51 -0
  129. package/templates/multi-repo/docs/release-notes.md +99 -0
  130. package/templates/multi-repo/overview/architecture.md +102 -0
  131. package/templates/multi-repo/overview/requirements.md +68 -0
  132. package/templates/multi-repo/overview/sequence.md +79 -0
  133. package/templates/multi-repo/steering/multi-repo.md +74 -0
  134. package/templates/multi-repo/tests/strategy.md +89 -0
  135. package/dist/scripts/__tests__/create-project.test.d.ts +0 -2
  136. package/dist/scripts/__tests__/create-project.test.d.ts.map +0 -1
  137. package/dist/scripts/__tests__/create-project.test.js +0 -243
  138. package/dist/scripts/__tests__/create-project.test.js.map +0 -1
  139. package/dist/scripts/__tests__/jira-transitions.test.d.ts +0 -5
  140. package/dist/scripts/__tests__/jira-transitions.test.d.ts.map +0 -1
  141. package/dist/scripts/__tests__/jira-transitions.test.js +0 -172
  142. package/dist/scripts/__tests__/jira-transitions.test.js.map +0 -1
  143. package/dist/scripts/__tests__/multi-project-estimate.test.d.ts +0 -2
  144. package/dist/scripts/__tests__/multi-project-estimate.test.d.ts.map +0 -1
  145. package/dist/scripts/__tests__/multi-project-estimate.test.js +0 -118
  146. package/dist/scripts/__tests__/multi-project-estimate.test.js.map +0 -1
  147. package/dist/scripts/__tests__/setup-existing-project.test.d.ts +0 -2
  148. package/dist/scripts/__tests__/setup-existing-project.test.d.ts.map +0 -1
  149. package/dist/scripts/__tests__/setup-existing-project.test.js +0 -208
  150. package/dist/scripts/__tests__/setup-existing-project.test.js.map +0 -1
  151. package/dist/scripts/__tests__/setup-interactive.test.d.ts +0 -2
  152. package/dist/scripts/__tests__/setup-interactive.test.d.ts.map +0 -1
  153. package/dist/scripts/__tests__/setup-interactive.test.js +0 -166
  154. package/dist/scripts/__tests__/setup-interactive.test.js.map +0 -1
  155. package/dist/scripts/__tests__/spec-impl-workflow.test.d.ts +0 -5
  156. package/dist/scripts/__tests__/spec-impl-workflow.test.d.ts.map +0 -1
  157. package/dist/scripts/__tests__/spec-impl-workflow.test.js +0 -323
  158. package/dist/scripts/__tests__/spec-impl-workflow.test.js.map +0 -1
  159. package/dist/scripts/__tests__/spec-loader.test.d.ts +0 -5
  160. package/dist/scripts/__tests__/spec-loader.test.d.ts.map +0 -1
  161. package/dist/scripts/__tests__/spec-loader.test.js +0 -153
  162. package/dist/scripts/__tests__/spec-loader.test.js.map +0 -1
  163. package/dist/scripts/__tests__/validate-phase.test.d.ts +0 -5
  164. package/dist/scripts/__tests__/validate-phase.test.d.ts.map +0 -1
  165. package/dist/scripts/__tests__/validate-phase.test.js +0 -249
  166. package/dist/scripts/__tests__/validate-phase.test.js.map +0 -1
  167. package/dist/scripts/constants/__tests__/environments.test.d.ts +0 -2
  168. package/dist/scripts/constants/__tests__/environments.test.d.ts.map +0 -1
  169. package/dist/scripts/constants/__tests__/environments.test.js +0 -125
  170. package/dist/scripts/constants/__tests__/environments.test.js.map +0 -1
  171. package/dist/scripts/constants/__tests__/languages.test.d.ts +0 -2
  172. package/dist/scripts/constants/__tests__/languages.test.d.ts.map +0 -1
  173. package/dist/scripts/constants/__tests__/languages.test.js +0 -82
  174. package/dist/scripts/constants/__tests__/languages.test.js.map +0 -1
  175. package/dist/scripts/create-project.d.ts +0 -16
  176. package/dist/scripts/create-project.d.ts.map +0 -1
  177. package/dist/scripts/create-project.js +0 -334
  178. package/dist/scripts/create-project.js.map +0 -1
  179. package/dist/scripts/list-projects.d.ts +0 -7
  180. package/dist/scripts/list-projects.d.ts.map +0 -1
  181. package/dist/scripts/list-projects.js +0 -88
  182. package/dist/scripts/list-projects.js.map +0 -1
  183. package/dist/scripts/template/__tests__/renderer.test.d.ts +0 -2
  184. package/dist/scripts/template/__tests__/renderer.test.d.ts.map +0 -1
  185. package/dist/scripts/template/__tests__/renderer.test.js +0 -165
  186. package/dist/scripts/template/__tests__/renderer.test.js.map +0 -1
  187. package/dist/scripts/utils/__tests__/aidlc-parser.test.d.ts +0 -5
  188. package/dist/scripts/utils/__tests__/aidlc-parser.test.d.ts.map +0 -1
  189. package/dist/scripts/utils/__tests__/aidlc-parser.test.js +0 -315
  190. package/dist/scripts/utils/__tests__/aidlc-parser.test.js.map +0 -1
  191. package/dist/scripts/utils/__tests__/business-days.test.d.ts +0 -5
  192. package/dist/scripts/utils/__tests__/business-days.test.d.ts.map +0 -1
  193. package/dist/scripts/utils/__tests__/business-days.test.js +0 -171
  194. package/dist/scripts/utils/__tests__/business-days.test.js.map +0 -1
  195. package/dist/scripts/utils/__tests__/config-loader.test.d.ts +0 -5
  196. package/dist/scripts/utils/__tests__/config-loader.test.d.ts.map +0 -1
  197. package/dist/scripts/utils/__tests__/config-loader.test.js +0 -314
  198. package/dist/scripts/utils/__tests__/config-loader.test.js.map +0 -1
  199. package/dist/scripts/utils/__tests__/config-validator.test.d.ts +0 -5
  200. package/dist/scripts/utils/__tests__/config-validator.test.d.ts.map +0 -1
  201. package/dist/scripts/utils/__tests__/config-validator.test.js +0 -396
  202. package/dist/scripts/utils/__tests__/config-validator.test.js.map +0 -1
  203. package/dist/scripts/utils/__tests__/env-config.test.d.ts +0 -5
  204. package/dist/scripts/utils/__tests__/env-config.test.d.ts.map +0 -1
  205. package/dist/scripts/utils/__tests__/env-config.test.js +0 -216
  206. package/dist/scripts/utils/__tests__/env-config.test.js.map +0 -1
  207. package/dist/scripts/utils/__tests__/feature-name-validator.test.d.ts +0 -5
  208. package/dist/scripts/utils/__tests__/feature-name-validator.test.d.ts.map +0 -1
  209. package/dist/scripts/utils/__tests__/feature-name-validator.test.js +0 -106
  210. package/dist/scripts/utils/__tests__/feature-name-validator.test.js.map +0 -1
  211. package/dist/scripts/utils/__tests__/jira-issue-type-fetcher.test.d.ts +0 -5
  212. package/dist/scripts/utils/__tests__/jira-issue-type-fetcher.test.d.ts.map +0 -1
  213. package/dist/scripts/utils/__tests__/jira-issue-type-fetcher.test.js +0 -202
  214. package/dist/scripts/utils/__tests__/jira-issue-type-fetcher.test.js.map +0 -1
  215. package/dist/scripts/utils/__tests__/project-meta.test.d.ts +0 -6
  216. package/dist/scripts/utils/__tests__/project-meta.test.d.ts.map +0 -1
  217. package/dist/scripts/utils/__tests__/project-meta.test.js +0 -154
  218. package/dist/scripts/utils/__tests__/project-meta.test.js.map +0 -1
  219. package/dist/scripts/utils/__tests__/security-validator.test.d.ts +0 -6
  220. package/dist/scripts/utils/__tests__/security-validator.test.d.ts.map +0 -1
  221. package/dist/scripts/utils/__tests__/security-validator.test.js +0 -219
  222. package/dist/scripts/utils/__tests__/security-validator.test.js.map +0 -1
  223. package/dist/scripts/utils/__tests__/spec-updater.test.d.ts +0 -5
  224. package/dist/scripts/utils/__tests__/spec-updater.test.d.ts.map +0 -1
  225. package/dist/scripts/utils/__tests__/spec-updater.test.js +0 -158
  226. package/dist/scripts/utils/__tests__/spec-updater.test.js.map +0 -1
  227. package/dist/scripts/utils/__tests__/tasks-converter.test.d.ts +0 -5
  228. package/dist/scripts/utils/__tests__/tasks-converter.test.d.ts.map +0 -1
  229. package/dist/scripts/utils/__tests__/tasks-converter.test.js +0 -500
  230. package/dist/scripts/utils/__tests__/tasks-converter.test.js.map +0 -1
  231. package/dist/scripts/utils/__tests__/tasks-format-validator.test.d.ts +0 -5
  232. package/dist/scripts/utils/__tests__/tasks-format-validator.test.d.ts.map +0 -1
  233. package/dist/scripts/utils/__tests__/tasks-format-validator.test.js +0 -314
  234. package/dist/scripts/utils/__tests__/tasks-format-validator.test.js.map +0 -1
  235. package/dist/scripts/utils/__tests__/test-runner.test.d.ts +0 -5
  236. package/dist/scripts/utils/__tests__/test-runner.test.d.ts.map +0 -1
  237. package/dist/scripts/utils/__tests__/test-runner.test.js +0 -64
  238. package/dist/scripts/utils/__tests__/test-runner.test.js.map +0 -1
  239. package/dist/src/__tests__/cli.test.d.ts +0 -5
  240. package/dist/src/__tests__/cli.test.d.ts.map +0 -1
  241. package/dist/src/__tests__/cli.test.js +0 -58
  242. package/dist/src/__tests__/cli.test.js.map +0 -1
  243. package/dist/src/__tests__/integration/internationalization.test.d.ts +0 -8
  244. package/dist/src/__tests__/integration/internationalization.test.d.ts.map +0 -1
  245. package/dist/src/__tests__/integration/internationalization.test.js +0 -333
  246. package/dist/src/__tests__/integration/internationalization.test.js.map +0 -1
  247. package/dist/src/__tests__/integration/setup/claude-agent.test.d.ts +0 -5
  248. package/dist/src/__tests__/integration/setup/claude-agent.test.d.ts.map +0 -1
  249. package/dist/src/__tests__/integration/setup/claude-agent.test.js +0 -122
  250. package/dist/src/__tests__/integration/setup/claude-agent.test.js.map +0 -1
  251. package/dist/src/__tests__/integration/setup/claude.test.d.ts +0 -5
  252. package/dist/src/__tests__/integration/setup/claude.test.d.ts.map +0 -1
  253. package/dist/src/__tests__/integration/setup/claude.test.js +0 -193
  254. package/dist/src/__tests__/integration/setup/claude.test.js.map +0 -1
  255. package/dist/src/__tests__/integration/setup/cursor.test.d.ts +0 -5
  256. package/dist/src/__tests__/integration/setup/cursor.test.d.ts.map +0 -1
  257. package/dist/src/__tests__/integration/setup/cursor.test.js +0 -166
  258. package/dist/src/__tests__/integration/setup/cursor.test.js.map +0 -1
  259. package/dist/src/__tests__/integration/setup/helpers/fs-assertions.d.ts +0 -32
  260. package/dist/src/__tests__/integration/setup/helpers/fs-assertions.d.ts.map +0 -1
  261. package/dist/src/__tests__/integration/setup/helpers/fs-assertions.js +0 -72
  262. package/dist/src/__tests__/integration/setup/helpers/fs-assertions.js.map +0 -1
  263. package/dist/src/__tests__/integration/setup/helpers/test-project.d.ts +0 -38
  264. package/dist/src/__tests__/integration/setup/helpers/test-project.d.ts.map +0 -1
  265. package/dist/src/__tests__/integration/setup/helpers/test-project.js +0 -83
  266. package/dist/src/__tests__/integration/setup/helpers/test-project.js.map +0 -1
  267. package/dist/src/__tests__/integration/setup/init.test.d.ts +0 -5
  268. package/dist/src/__tests__/integration/setup/init.test.d.ts.map +0 -1
  269. package/dist/src/__tests__/integration/setup/init.test.js +0 -352
  270. package/dist/src/__tests__/integration/setup/init.test.js.map +0 -1
  271. package/dist/src/__tests__/integration/setup/validation.test.d.ts +0 -5
  272. package/dist/src/__tests__/integration/setup/validation.test.d.ts.map +0 -1
  273. package/dist/src/__tests__/integration/setup/validation.test.js +0 -301
  274. package/dist/src/__tests__/integration/setup/validation.test.js.map +0 -1
  275. package/dist/src/commands/__tests__/init.test.d.ts +0 -5
  276. package/dist/src/commands/__tests__/init.test.d.ts.map +0 -1
  277. package/dist/src/commands/__tests__/init.test.js +0 -255
  278. package/dist/src/commands/__tests__/init.test.js.map +0 -1
  279. package/dist/src/commands/__tests__/migrate.test.d.ts +0 -5
  280. package/dist/src/commands/__tests__/migrate.test.d.ts.map +0 -1
  281. package/dist/src/commands/__tests__/migrate.test.js +0 -216
  282. package/dist/src/commands/__tests__/migrate.test.js.map +0 -1
  283. package/scripts/create-project.ts +0 -386
  284. package/scripts/list-projects.ts +0 -112
@@ -0,0 +1,335 @@
1
+ /**
2
+ * Multi-Repo設定スキーマのテスト
3
+ * Task 1.1: Multi-Repo設定のZodスキーマを定義
4
+ */
5
+
6
+ import { describe, it, expect } from 'vitest';
7
+ import {
8
+ RepositorySchema,
9
+ MultiRepoProjectSchema,
10
+ } from '../config/config-schema';
11
+
12
+ describe('RepositorySchema', () => {
13
+ describe('正常ケース', () => {
14
+ it('有効なリポジトリ情報を受け入れる', () => {
15
+ const validRepo = {
16
+ name: 'my-repo',
17
+ url: 'https://github.com/owner/repo',
18
+ branch: 'main',
19
+ };
20
+
21
+ const result = RepositorySchema.safeParse(validRepo);
22
+ expect(result.success).toBe(true);
23
+ if (result.success) {
24
+ expect(result.data).toEqual(validRepo);
25
+ }
26
+ });
27
+
28
+ it('branchのデフォルト値は"main"', () => {
29
+ const repoWithoutBranch = {
30
+ name: 'my-repo',
31
+ url: 'https://github.com/owner/repo',
32
+ };
33
+
34
+ const result = RepositorySchema.safeParse(repoWithoutBranch);
35
+ expect(result.success).toBe(true);
36
+ if (result.success) {
37
+ expect(result.data.branch).toBe('main');
38
+ }
39
+ });
40
+ });
41
+
42
+ describe('異常ケース', () => {
43
+ it('リポジトリ名が空文字列の場合はエラー', () => {
44
+ const invalidRepo = {
45
+ name: '',
46
+ url: 'https://github.com/owner/repo',
47
+ branch: 'main',
48
+ };
49
+
50
+ const result = RepositorySchema.safeParse(invalidRepo);
51
+ expect(result.success).toBe(false);
52
+ });
53
+
54
+ it('無効なGitHub URL形式の場合はエラー', () => {
55
+ const invalidRepo = {
56
+ name: 'my-repo',
57
+ url: 'https://gitlab.com/owner/repo', // GitLabは非対応
58
+ branch: 'main',
59
+ };
60
+
61
+ const result = RepositorySchema.safeParse(invalidRepo);
62
+ expect(result.success).toBe(false);
63
+ });
64
+
65
+ it('URLにhttps以外のプロトコルが含まれる場合はエラー', () => {
66
+ const invalidRepo = {
67
+ name: 'my-repo',
68
+ url: 'http://github.com/owner/repo', // httpは非対応
69
+ branch: 'main',
70
+ };
71
+
72
+ const result = RepositorySchema.safeParse(invalidRepo);
73
+ expect(result.success).toBe(false);
74
+ });
75
+ });
76
+ });
77
+
78
+ describe('MultiRepoProjectSchema', () => {
79
+ describe('正常ケース', () => {
80
+ it('有効なプロジェクト情報を受け入れる', () => {
81
+ const validProject = {
82
+ name: 'my-project',
83
+ jiraKey: 'PROJ',
84
+ confluenceSpace: 'SPACE',
85
+ createdAt: '2025-12-14T10:00:00Z',
86
+ repositories: [
87
+ {
88
+ name: 'repo1',
89
+ url: 'https://github.com/owner/repo1',
90
+ branch: 'main',
91
+ },
92
+ ],
93
+ };
94
+
95
+ const result = MultiRepoProjectSchema.safeParse(validProject);
96
+ expect(result.success).toBe(true);
97
+ if (result.success) {
98
+ expect(result.data).toEqual(validProject);
99
+ }
100
+ });
101
+
102
+ it('repositories配列が空の場合も受け入れる', () => {
103
+ const projectWithoutRepos = {
104
+ name: 'my-project',
105
+ jiraKey: 'PROJ',
106
+ confluenceSpace: 'SPACE',
107
+ createdAt: '2025-12-14T10:00:00Z',
108
+ repositories: [],
109
+ };
110
+
111
+ const result = MultiRepoProjectSchema.safeParse(projectWithoutRepos);
112
+ expect(result.success).toBe(true);
113
+ });
114
+
115
+ it('日本語のプロジェクト名を受け入れる', () => {
116
+ const validProject = {
117
+ name: 'プロジェクト名',
118
+ jiraKey: 'PROJ',
119
+ confluenceSpace: 'SPACE',
120
+ createdAt: '2025-12-14T10:00:00Z',
121
+ repositories: [],
122
+ };
123
+
124
+ const result = MultiRepoProjectSchema.safeParse(validProject);
125
+ expect(result.success).toBe(true);
126
+ });
127
+
128
+ it('ハイフン、アンダースコアを含むプロジェクト名を受け入れる', () => {
129
+ const validProject = {
130
+ name: 'my-project_v2',
131
+ jiraKey: 'PROJ',
132
+ confluenceSpace: 'SPACE',
133
+ createdAt: '2025-12-14T10:00:00Z',
134
+ repositories: [],
135
+ };
136
+
137
+ const result = MultiRepoProjectSchema.safeParse(validProject);
138
+ expect(result.success).toBe(true);
139
+ });
140
+ });
141
+
142
+ describe('プロジェクト名バリデーション', () => {
143
+ const createProject = (name: string) => ({
144
+ name,
145
+ jiraKey: 'PROJ',
146
+ confluenceSpace: 'SPACE',
147
+ createdAt: '2025-12-14T10:00:00Z',
148
+ repositories: [],
149
+ });
150
+
151
+ it('パストラバーサル(../)を含む場合はエラー', () => {
152
+ const result = MultiRepoProjectSchema.safeParse(
153
+ createProject('../etc/passwd'),
154
+ );
155
+ expect(result.success).toBe(false);
156
+ });
157
+
158
+ it('パストラバーサル(/)を含む場合はエラー', () => {
159
+ const result =
160
+ MultiRepoProjectSchema.safeParse(createProject('/etc/passwd'));
161
+ expect(result.success).toBe(false);
162
+ });
163
+
164
+ it('Windowsパス区切り(\\)を含む場合はエラー', () => {
165
+ const result = MultiRepoProjectSchema.safeParse(
166
+ createProject('..\\windows\\system32'),
167
+ );
168
+ expect(result.success).toBe(false);
169
+ });
170
+
171
+ it('相対パス(.)を含む場合はエラー', () => {
172
+ const result = MultiRepoProjectSchema.safeParse(createProject('.'));
173
+ expect(result.success).toBe(false);
174
+ });
175
+
176
+ it('相対パス(..)を含む場合はエラー', () => {
177
+ const result = MultiRepoProjectSchema.safeParse(createProject('..'));
178
+ expect(result.success).toBe(false);
179
+ });
180
+
181
+ it('制御文字(\\x00)を含む場合はエラー', () => {
182
+ const result = MultiRepoProjectSchema.safeParse(
183
+ createProject('project\x00name'),
184
+ );
185
+ expect(result.success).toBe(false);
186
+ });
187
+
188
+ it('制御文字(\\t)を含む場合はエラー', () => {
189
+ const result = MultiRepoProjectSchema.safeParse(
190
+ createProject('project\tname'),
191
+ );
192
+ expect(result.success).toBe(false);
193
+ });
194
+
195
+ it('制御文字(\\n)を含む場合はエラー', () => {
196
+ const result = MultiRepoProjectSchema.safeParse(
197
+ createProject('project\nname'),
198
+ );
199
+ expect(result.success).toBe(false);
200
+ });
201
+
202
+ it('制御文字(\\r)を含む場合はエラー', () => {
203
+ const result = MultiRepoProjectSchema.safeParse(
204
+ createProject('project\rname'),
205
+ );
206
+ expect(result.success).toBe(false);
207
+ });
208
+
209
+ it('制御文字(\\x1B)を含む場合はエラー', () => {
210
+ const result = MultiRepoProjectSchema.safeParse(
211
+ createProject('project\x1Bname'),
212
+ );
213
+ expect(result.success).toBe(false);
214
+ });
215
+
216
+ it('制御文字(\\x7F)を含む場合はエラー', () => {
217
+ const result = MultiRepoProjectSchema.safeParse(
218
+ createProject('project\x7Fname'),
219
+ );
220
+ expect(result.success).toBe(false);
221
+ });
222
+
223
+ it('101文字以上のプロジェクト名はエラー', () => {
224
+ const longName = 'a'.repeat(101);
225
+ const result = MultiRepoProjectSchema.safeParse(createProject(longName));
226
+ expect(result.success).toBe(false);
227
+ });
228
+
229
+ it('空文字列のプロジェクト名はエラー', () => {
230
+ const result = MultiRepoProjectSchema.safeParse(createProject(''));
231
+ expect(result.success).toBe(false);
232
+ });
233
+ });
234
+
235
+ describe('JIRAキーバリデーション', () => {
236
+ const createProject = (jiraKey: string) => ({
237
+ name: 'my-project',
238
+ jiraKey,
239
+ confluenceSpace: 'SPACE',
240
+ createdAt: '2025-12-14T10:00:00Z',
241
+ repositories: [],
242
+ });
243
+
244
+ it('2-10文字の大文字英字を受け入れる', () => {
245
+ const validKeys = ['AB', 'PROJ', 'TICKET', 'ABCDEFGHIJ'];
246
+ validKeys.forEach((key) => {
247
+ const result = MultiRepoProjectSchema.safeParse(createProject(key));
248
+ expect(result.success).toBe(true);
249
+ });
250
+ });
251
+
252
+ it('小文字を含む場合はエラー', () => {
253
+ const result = MultiRepoProjectSchema.safeParse(createProject('abc'));
254
+ expect(result.success).toBe(false);
255
+ });
256
+
257
+ it('1文字の場合はエラー', () => {
258
+ const result = MultiRepoProjectSchema.safeParse(createProject('A'));
259
+ expect(result.success).toBe(false);
260
+ });
261
+
262
+ it('11文字以上の場合はエラー', () => {
263
+ const result =
264
+ MultiRepoProjectSchema.safeParse(createProject('ABCDEFGHIJK'));
265
+ expect(result.success).toBe(false);
266
+ });
267
+
268
+ it('数字を含む場合はエラー', () => {
269
+ const result = MultiRepoProjectSchema.safeParse(createProject('ABC123'));
270
+ expect(result.success).toBe(false);
271
+ });
272
+
273
+ it('空文字列の場合はエラー', () => {
274
+ const result = MultiRepoProjectSchema.safeParse(createProject(''));
275
+ expect(result.success).toBe(false);
276
+ });
277
+ });
278
+
279
+ describe('Confluenceスペースキーバリデーション', () => {
280
+ const createProject = (confluenceSpace: string) => ({
281
+ name: 'my-project',
282
+ jiraKey: 'PROJ',
283
+ confluenceSpace,
284
+ createdAt: '2025-12-14T10:00:00Z',
285
+ repositories: [],
286
+ });
287
+
288
+ it('非空文字列を受け入れる', () => {
289
+ const result = MultiRepoProjectSchema.safeParse(createProject('SPACE'));
290
+ expect(result.success).toBe(true);
291
+ });
292
+
293
+ it('空文字列の場合はエラー', () => {
294
+ const result = MultiRepoProjectSchema.safeParse(createProject(''));
295
+ expect(result.success).toBe(false);
296
+ });
297
+ });
298
+
299
+ describe('createdAtバリデーション', () => {
300
+ const createProject = (createdAt: string) => ({
301
+ name: 'my-project',
302
+ jiraKey: 'PROJ',
303
+ confluenceSpace: 'SPACE',
304
+ createdAt,
305
+ repositories: [],
306
+ });
307
+
308
+ it('ISO 8601形式を受け入れる', () => {
309
+ const validDates = [
310
+ '2025-12-14T10:00:00Z',
311
+ '2025-12-14T10:00:00.000Z',
312
+ '2025-12-14T10:00:00+09:00',
313
+ ];
314
+ validDates.forEach((date) => {
315
+ const result = MultiRepoProjectSchema.safeParse(createProject(date));
316
+ if (!result.success) {
317
+ console.log(`Failed for date: ${date}`);
318
+ console.log('Error:', result.error.issues);
319
+ }
320
+ expect(result.success).toBe(true);
321
+ });
322
+ });
323
+
324
+ it('無効な日付形式の場合はエラー', () => {
325
+ const result =
326
+ MultiRepoProjectSchema.safeParse(createProject('2025/12/14 10:00:00'));
327
+ expect(result.success).toBe(false);
328
+ });
329
+
330
+ it('空文字列の場合はエラー', () => {
331
+ const result = MultiRepoProjectSchema.safeParse(createProject(''));
332
+ expect(result.success).toBe(false);
333
+ });
334
+ });
335
+ });