create-einja-app 0.1.1 → 0.1.2

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 (242) hide show
  1. package/README.md +3 -7
  2. package/dist/cli.js +11 -49
  3. package/dist/cli.js.map +1 -1
  4. package/package.json +1 -1
  5. package/templates/default/.playwright-mcp/dashboard.png +0 -0
  6. package/templates/default/.playwright-mcp/web-home.png +0 -0
  7. package/templates/{turborepo-pandacss → default}/CLAUDE.md +5 -5
  8. package/templates/default/apps/web/server/presentation/routes/userRoutes.ts +57 -0
  9. package/templates/{turborepo-pandacss → default}/apps/web/src/app/(authenticated)/data/_components/UserTable.tsx +18 -7
  10. package/templates/default/apps/web/src/app/(authenticated)/data/_components/UserTableContainer.tsx +62 -0
  11. package/templates/{turborepo-pandacss → default}/apps/web/src/app/(authenticated)/data/page.tsx +13 -8
  12. package/templates/default/apps/web/src/app/api/rpc/[[...route]]/route.ts +31 -0
  13. package/templates/default/apps/web/src/hooks/use-users.ts +118 -0
  14. package/templates/default/apps/web/src/lib/api-client.ts +18 -0
  15. package/templates/{turborepo-pandacss → default}/apps/web/tsconfig.json +5 -0
  16. package/templates/{turborepo-pandacss → default}/package.json +7 -2
  17. package/templates/default/packages/server-core/src/domain/validators/user.ts +23 -0
  18. package/templates/{turborepo-pandacss → default}/pnpm-lock.yaml +21 -3
  19. /package/templates/{turborepo-pandacss → default}/.biomeignore +0 -0
  20. /package/templates/{turborepo-pandacss → default}/.claude/hooks/einja/biome-format.sh +0 -0
  21. /package/templates/{turborepo-pandacss → default}/.claude/hooks/einja/design-doc-check.sh +0 -0
  22. /package/templates/{turborepo-pandacss → default}/.claude/hooks/einja/detect-secrets.sh +0 -0
  23. /package/templates/{turborepo-pandacss → default}/.claude/hooks/einja/large-file-warning.sh +0 -0
  24. /package/templates/{turborepo-pandacss → default}/.claude/hooks/einja/playwright-resize.sh +0 -0
  25. /package/templates/{turborepo-pandacss → default}/.claude/hooks/einja/typecheck.sh +0 -0
  26. /package/templates/{turborepo-pandacss → default}/.claude/hooks/einja/unset-volta-recursion.sh +0 -0
  27. /package/templates/{turborepo-pandacss → default}/.claude/hooks/einja/validate-git-commit.sh +0 -0
  28. /package/templates/{turborepo-pandacss → default}/.claude/hooks/einja/warn-index-ts.sh +0 -0
  29. /package/templates/{turborepo-pandacss → default}/.claude/hooks/einja/warn-relative-import.sh +0 -0
  30. /package/templates/{turborepo-pandacss → default}/.claude/settings.json +0 -0
  31. /package/templates/{turborepo-pandacss → default}/.claude/skills/create-einja-app-release/SKILL.md +0 -0
  32. /package/templates/{turborepo-pandacss → default}/.claude/skills/dev-cli-release/SKILL.md +0 -0
  33. /package/templates/{turborepo-pandacss → default}/.cursor/commands/spec-create.md +0 -0
  34. /package/templates/{turborepo-pandacss → default}/.cursor/commands/start-dev.md +0 -0
  35. /package/templates/{turborepo-pandacss → default}/.cursor/commands/task-exec.md +0 -0
  36. /package/templates/{turborepo-pandacss → default}/.cursor/commands/task-vibe-kanban-loop.md +0 -0
  37. /package/templates/{turborepo-pandacss → default}/.cursor/commands/update-docs-by-task-specs.md +0 -0
  38. /package/templates/{turborepo-pandacss → default}/.cursor/mcp.json +0 -0
  39. /package/templates/{turborepo-pandacss → default}/.cursor/rules/api-rules.mdc +0 -0
  40. /package/templates/{turborepo-pandacss → default}/.cursor/rules/api-test-rules.mdc +0 -0
  41. /package/templates/{turborepo-pandacss → default}/.cursor/rules/base-code.mdc +0 -0
  42. /package/templates/{turborepo-pandacss → default}/.cursor/rules/base-commit-rules.mdc +0 -0
  43. /package/templates/{turborepo-pandacss → default}/.cursor/rules/base-design.mdc +0 -0
  44. /package/templates/{turborepo-pandacss → default}/.cursor/rules/base-rules.mdc +0 -0
  45. /package/templates/{turborepo-pandacss → default}/.cursor/rules/error-handling-rules.mdc +0 -0
  46. /package/templates/{turborepo-pandacss → default}/.cursor/rules/refactor-rules.mdc +0 -0
  47. /package/templates/{turborepo-pandacss → default}/.dockerignore +0 -0
  48. /package/templates/{turborepo-pandacss → default}/.einja-sync.json +0 -0
  49. /package/templates/{turborepo-pandacss → default}/.env.ci +0 -0
  50. /package/templates/{turborepo-pandacss → default}/.env.example +0 -0
  51. /package/templates/{turborepo-pandacss → default}/.env.personal.example +0 -0
  52. /package/templates/{turborepo-pandacss → default}/.envrc +0 -0
  53. /package/templates/{turborepo-pandacss → default}/.gitattributes +0 -0
  54. /package/templates/{turborepo-pandacss → default}/.husky/pre-commit +0 -0
  55. /package/templates/{turborepo-pandacss → default}/.lintstagedrc.js +0 -0
  56. /package/templates/{turborepo-pandacss → default}/.mcp.json +0 -0
  57. /package/templates/{turborepo-pandacss → default}/.node-version +0 -0
  58. /package/templates/{turborepo-pandacss → default}/.templateignore +0 -0
  59. /package/templates/{turborepo-pandacss → default}/.vscode/extensions.json +0 -0
  60. /package/templates/{turborepo-pandacss → default}/README.md +0 -0
  61. /package/templates/{turborepo-pandacss → default}/apps/web/middleware.ts +0 -0
  62. /package/templates/{turborepo-pandacss → default}/apps/web/next.config.ts +0 -0
  63. /package/templates/{turborepo-pandacss → default}/apps/web/package.json +0 -0
  64. /package/templates/{turborepo-pandacss → default}/apps/web/panda.config.ts +0 -0
  65. /package/templates/{turborepo-pandacss → default}/apps/web/postcss.config.cjs +0 -0
  66. /package/templates/{turborepo-pandacss → default}/apps/web/public/file.svg +0 -0
  67. /package/templates/{turborepo-pandacss → default}/apps/web/public/globe.svg +0 -0
  68. /package/templates/{turborepo-pandacss → default}/apps/web/public/next.svg +0 -0
  69. /package/templates/{turborepo-pandacss → default}/apps/web/public/vercel.svg +0 -0
  70. /package/templates/{turborepo-pandacss → default}/apps/web/public/window.svg +0 -0
  71. /package/templates/{turborepo-pandacss → default}/apps/web/src/app/(authenticated)/dashboard/page.tsx +0 -0
  72. /package/templates/{turborepo-pandacss → default}/apps/web/src/app/(authenticated)/layout-client.tsx +0 -0
  73. /package/templates/{turborepo-pandacss → default}/apps/web/src/app/(authenticated)/layout.tsx +0 -0
  74. /package/templates/{turborepo-pandacss → default}/apps/web/src/app/(authenticated)/profile/page.tsx +0 -0
  75. /package/templates/{turborepo-pandacss → default}/apps/web/src/app/api/auth/[...nextauth]/route.ts +0 -0
  76. /package/templates/{turborepo-pandacss → default}/apps/web/src/app/api/auth/signup/route.ts +0 -0
  77. /package/templates/{turborepo-pandacss → default}/apps/web/src/app/error.tsx +0 -0
  78. /package/templates/{turborepo-pandacss → default}/apps/web/src/app/favicon.ico +0 -0
  79. /package/templates/{turborepo-pandacss → default}/apps/web/src/app/global-error.tsx +0 -0
  80. /package/templates/{turborepo-pandacss → default}/apps/web/src/app/globals.css +0 -0
  81. /package/templates/{turborepo-pandacss → default}/apps/web/src/app/layout.tsx +0 -0
  82. /package/templates/{turborepo-pandacss → default}/apps/web/src/app/not-found.tsx +0 -0
  83. /package/templates/{turborepo-pandacss → default}/apps/web/src/app/page.module.css +0 -0
  84. /package/templates/{turborepo-pandacss → default}/apps/web/src/app/page.test.tsx +0 -0
  85. /package/templates/{turborepo-pandacss → default}/apps/web/src/app/page.tsx +0 -0
  86. /package/templates/{turborepo-pandacss → default}/apps/web/src/app/signin/page.tsx +0 -0
  87. /package/templates/{turborepo-pandacss → default}/apps/web/src/app/signup/page.tsx +0 -0
  88. /package/templates/{turborepo-pandacss → default}/apps/web/src/application/use-cases/UserUseCases.test.ts +0 -0
  89. /package/templates/{turborepo-pandacss → default}/apps/web/src/application/use-cases/UserUseCases.ts +0 -0
  90. /package/templates/{turborepo-pandacss → default}/apps/web/src/components/auth/login-button.tsx +0 -0
  91. /package/templates/{turborepo-pandacss → default}/apps/web/src/components/auth/logout-button.tsx +0 -0
  92. /package/templates/{turborepo-pandacss → default}/apps/web/src/components/auth/user-avatar.test.tsx +0 -0
  93. /package/templates/{turborepo-pandacss → default}/apps/web/src/components/auth/user-avatar.tsx +0 -0
  94. /package/templates/{turborepo-pandacss → default}/apps/web/src/components/dashboard/dashboard-stats.tsx +0 -0
  95. /package/templates/{turborepo-pandacss → default}/apps/web/src/components/providers/query-provider.tsx +0 -0
  96. /package/templates/{turborepo-pandacss → default}/apps/web/src/components/providers/session-provider.tsx +0 -0
  97. /package/templates/{turborepo-pandacss → default}/apps/web/src/components/shared/Sidebar.tsx +0 -0
  98. /package/templates/{turborepo-pandacss → default}/apps/web/src/components/shared/header.tsx +0 -0
  99. /package/templates/{turborepo-pandacss → default}/apps/web/src/components/ui/accordion.tsx +0 -0
  100. /package/templates/{turborepo-pandacss → default}/apps/web/src/components/ui/alert-dialog.tsx +0 -0
  101. /package/templates/{turborepo-pandacss → default}/apps/web/src/components/ui/alert.tsx +0 -0
  102. /package/templates/{turborepo-pandacss → default}/apps/web/src/components/ui/aspect-ratio.tsx +0 -0
  103. /package/templates/{turborepo-pandacss → default}/apps/web/src/components/ui/avatar.tsx +0 -0
  104. /package/templates/{turborepo-pandacss → default}/apps/web/src/components/ui/badge.tsx +0 -0
  105. /package/templates/{turborepo-pandacss → default}/apps/web/src/components/ui/breadcrumb.tsx +0 -0
  106. /package/templates/{turborepo-pandacss → default}/apps/web/src/components/ui/button.tsx +0 -0
  107. /package/templates/{turborepo-pandacss → default}/apps/web/src/components/ui/card.tsx +0 -0
  108. /package/templates/{turborepo-pandacss → default}/apps/web/src/components/ui/checkbox.tsx +0 -0
  109. /package/templates/{turborepo-pandacss → default}/apps/web/src/components/ui/data-table.tsx +0 -0
  110. /package/templates/{turborepo-pandacss → default}/apps/web/src/components/ui/dialog-hook.tsx +0 -0
  111. /package/templates/{turborepo-pandacss → default}/apps/web/src/components/ui/dialog.tsx +0 -0
  112. /package/templates/{turborepo-pandacss → default}/apps/web/src/components/ui/drawer.tsx +0 -0
  113. /package/templates/{turborepo-pandacss → default}/apps/web/src/components/ui/dropdown-menu.tsx +0 -0
  114. /package/templates/{turborepo-pandacss → default}/apps/web/src/components/ui/form.tsx +0 -0
  115. /package/templates/{turborepo-pandacss → default}/apps/web/src/components/ui/hover-card.tsx +0 -0
  116. /package/templates/{turborepo-pandacss → default}/apps/web/src/components/ui/input.tsx +0 -0
  117. /package/templates/{turborepo-pandacss → default}/apps/web/src/components/ui/label.tsx +0 -0
  118. /package/templates/{turborepo-pandacss → default}/apps/web/src/components/ui/pagination.tsx +0 -0
  119. /package/templates/{turborepo-pandacss → default}/apps/web/src/components/ui/popover.tsx +0 -0
  120. /package/templates/{turborepo-pandacss → default}/apps/web/src/components/ui/progress.tsx +0 -0
  121. /package/templates/{turborepo-pandacss → default}/apps/web/src/components/ui/select.tsx +0 -0
  122. /package/templates/{turborepo-pandacss → default}/apps/web/src/components/ui/separator.tsx +0 -0
  123. /package/templates/{turborepo-pandacss → default}/apps/web/src/components/ui/skeleton.tsx +0 -0
  124. /package/templates/{turborepo-pandacss → default}/apps/web/src/components/ui/sonner.tsx +0 -0
  125. /package/templates/{turborepo-pandacss → default}/apps/web/src/components/ui/table.tsx +0 -0
  126. /package/templates/{turborepo-pandacss → default}/apps/web/src/components/ui/tabs.tsx +0 -0
  127. /package/templates/{turborepo-pandacss → default}/apps/web/src/components/ui/textarea.tsx +0 -0
  128. /package/templates/{turborepo-pandacss → default}/apps/web/src/components/ui/tooltip.tsx +0 -0
  129. /package/templates/{turborepo-pandacss → default}/apps/web/src/components/ui/typography.tsx +0 -0
  130. /package/templates/{turborepo-pandacss → default}/apps/web/src/lib/auth/guard.ts +0 -0
  131. /package/templates/{turborepo-pandacss → default}/apps/web/src/lib/auth/index.ts +0 -0
  132. /package/templates/{turborepo-pandacss → default}/apps/web/src/lib/prisma.ts +0 -0
  133. /package/templates/{turborepo-pandacss → default}/apps/web/src/lib/utils.ts +0 -0
  134. /package/templates/{turborepo-pandacss → default}/apps/web/test/globals.d.ts +0 -0
  135. /package/templates/{turborepo-pandacss → default}/apps/web/test/matchers.d.ts +0 -0
  136. /package/templates/{turborepo-pandacss → default}/apps/web/test/setup.ts +0 -0
  137. /package/templates/{turborepo-pandacss → default}/apps/web/vitest.config.ts +0 -0
  138. /package/templates/{turborepo-pandacss → default}/apps/web/vitest.d.ts +0 -0
  139. /package/templates/{turborepo-pandacss → default}/biome.json +0 -0
  140. /package/templates/{turborepo-pandacss → default}/components.json +0 -0
  141. /package/templates/{turborepo-pandacss → default}/docker-compose.yml +0 -0
  142. /package/templates/{turborepo-pandacss → default}/middleware.ts +0 -0
  143. /package/templates/{turborepo-pandacss → default}/next.config.ts +0 -0
  144. /package/templates/{turborepo-pandacss → default}/package-lock.json +0 -0
  145. /package/templates/{turborepo-pandacss → default}/packages/config/package.json +0 -0
  146. /package/templates/{turborepo-pandacss → default}/packages/config/panda.config.ts +0 -0
  147. /package/templates/{turborepo-pandacss → default}/packages/config/src/index.ts +0 -0
  148. /package/templates/{turborepo-pandacss → default}/packages/config/src/worktree-config-loader.ts +0 -0
  149. /package/templates/{turborepo-pandacss → default}/packages/config/src/worktree-config.ts +0 -0
  150. /package/templates/{turborepo-pandacss → default}/packages/config/tsconfig.build.json +0 -0
  151. /package/templates/{turborepo-pandacss → default}/packages/config/tsconfig.json +0 -0
  152. /package/templates/{turborepo-pandacss → default}/packages/config/typescript/base.json +0 -0
  153. /package/templates/{turborepo-pandacss → default}/packages/front-core/package.json +0 -0
  154. /package/templates/{turborepo-pandacss → default}/packages/front-core/src/auth/config.ts +0 -0
  155. /package/templates/{turborepo-pandacss → default}/packages/front-core/src/auth/index.ts +0 -0
  156. /package/templates/{turborepo-pandacss → default}/packages/front-core/src/auth/types/next-auth.d.ts +0 -0
  157. /package/templates/{turborepo-pandacss → default}/packages/front-core/src/auth/utils.ts +0 -0
  158. /package/templates/{turborepo-pandacss → default}/packages/front-core/src/context/index.ts +0 -0
  159. /package/templates/{turborepo-pandacss → default}/packages/front-core/src/hooks/index.ts +0 -0
  160. /package/templates/{turborepo-pandacss → default}/packages/front-core/src/index.ts +0 -0
  161. /package/templates/{turborepo-pandacss → default}/packages/front-core/src/utils/index.ts +0 -0
  162. /package/templates/{turborepo-pandacss → default}/packages/front-core/tsconfig.json +0 -0
  163. /package/templates/{turborepo-pandacss → default}/packages/server-core/package.json +0 -0
  164. /package/templates/{turborepo-pandacss → default}/packages/server-core/prisma/schema.prisma +0 -0
  165. /package/templates/{turborepo-pandacss → default}/packages/server-core/prisma/seed.ts +0 -0
  166. /package/templates/{turborepo-pandacss → default}/packages/server-core/prisma.config.ts +0 -0
  167. /package/templates/{turborepo-pandacss → default}/packages/server-core/src/__generated__/fabbrica/index.d.ts +0 -0
  168. /package/templates/{turborepo-pandacss → default}/packages/server-core/src/__generated__/fabbrica/index.js +0 -0
  169. /package/templates/{turborepo-pandacss → default}/packages/server-core/src/core/result.test.ts +0 -0
  170. /package/templates/{turborepo-pandacss → default}/packages/server-core/src/core/result.ts +0 -0
  171. /package/templates/{turborepo-pandacss → default}/packages/server-core/src/domain/.gitkeep +0 -0
  172. /package/templates/{turborepo-pandacss → default}/packages/server-core/src/domain/entities/User.test.ts +0 -0
  173. /package/templates/{turborepo-pandacss → default}/packages/server-core/src/domain/entities/User.ts +0 -0
  174. /package/templates/{turborepo-pandacss → default}/packages/server-core/src/domain/repository-interfaces/IUserRepository.ts +0 -0
  175. /package/templates/{turborepo-pandacss → default}/packages/server-core/src/infrastructure/database/client.ts +0 -0
  176. /package/templates/{turborepo-pandacss → default}/packages/server-core/src/infrastructure/database/mappers/UserMapper.test.ts +0 -0
  177. /package/templates/{turborepo-pandacss → default}/packages/server-core/src/infrastructure/database/mappers/UserMapper.ts +0 -0
  178. /package/templates/{turborepo-pandacss → default}/packages/server-core/src/infrastructure/database/repositories/UserRepository.test.ts +0 -0
  179. /package/templates/{turborepo-pandacss → default}/packages/server-core/src/infrastructure/database/repositories/UserRepository.ts +0 -0
  180. /package/templates/{turborepo-pandacss → default}/packages/server-core/src/testing/factories/index.ts +0 -0
  181. /package/templates/{turborepo-pandacss → default}/packages/server-core/src/testing/factories/user.factory.ts +0 -0
  182. /package/templates/{turborepo-pandacss → default}/packages/server-core/src/testing/fixtures/users.ts +0 -0
  183. /package/templates/{turborepo-pandacss → default}/packages/server-core/src/testing/helpers/date.ts +0 -0
  184. /package/templates/{turborepo-pandacss → default}/packages/server-core/src/testing/helpers/password.ts +0 -0
  185. /package/templates/{turborepo-pandacss → default}/packages/server-core/src/testing/index.ts +0 -0
  186. /package/templates/{turborepo-pandacss → default}/packages/server-core/tsconfig.json +0 -0
  187. /package/templates/{turborepo-pandacss → default}/packages/server-core/vitest.config.ts +0 -0
  188. /package/templates/{turborepo-pandacss → default}/packages/ui/package.json +0 -0
  189. /package/templates/{turborepo-pandacss → default}/packages/ui/src/accordion.tsx +0 -0
  190. /package/templates/{turborepo-pandacss → default}/packages/ui/src/alert-dialog.tsx +0 -0
  191. /package/templates/{turborepo-pandacss → default}/packages/ui/src/alert.tsx +0 -0
  192. /package/templates/{turborepo-pandacss → default}/packages/ui/src/aspect-ratio.tsx +0 -0
  193. /package/templates/{turborepo-pandacss → default}/packages/ui/src/avatar.tsx +0 -0
  194. /package/templates/{turborepo-pandacss → default}/packages/ui/src/badge.tsx +0 -0
  195. /package/templates/{turborepo-pandacss → default}/packages/ui/src/breadcrumb.tsx +0 -0
  196. /package/templates/{turborepo-pandacss → default}/packages/ui/src/button.tsx +0 -0
  197. /package/templates/{turborepo-pandacss → default}/packages/ui/src/card.tsx +0 -0
  198. /package/templates/{turborepo-pandacss → default}/packages/ui/src/checkbox.tsx +0 -0
  199. /package/templates/{turborepo-pandacss → default}/packages/ui/src/data-table.tsx +0 -0
  200. /package/templates/{turborepo-pandacss → default}/packages/ui/src/dialog-hook.tsx +0 -0
  201. /package/templates/{turborepo-pandacss → default}/packages/ui/src/dialog.tsx +0 -0
  202. /package/templates/{turborepo-pandacss → default}/packages/ui/src/drawer.tsx +0 -0
  203. /package/templates/{turborepo-pandacss → default}/packages/ui/src/dropdown-menu.tsx +0 -0
  204. /package/templates/{turborepo-pandacss → default}/packages/ui/src/form.tsx +0 -0
  205. /package/templates/{turborepo-pandacss → default}/packages/ui/src/hover-card.tsx +0 -0
  206. /package/templates/{turborepo-pandacss → default}/packages/ui/src/input.tsx +0 -0
  207. /package/templates/{turborepo-pandacss → default}/packages/ui/src/label.tsx +0 -0
  208. /package/templates/{turborepo-pandacss → default}/packages/ui/src/lib/utils.ts +0 -0
  209. /package/templates/{turborepo-pandacss → default}/packages/ui/src/pagination.tsx +0 -0
  210. /package/templates/{turborepo-pandacss → default}/packages/ui/src/popover.tsx +0 -0
  211. /package/templates/{turborepo-pandacss → default}/packages/ui/src/progress.tsx +0 -0
  212. /package/templates/{turborepo-pandacss → default}/packages/ui/src/select.tsx +0 -0
  213. /package/templates/{turborepo-pandacss → default}/packages/ui/src/separator.tsx +0 -0
  214. /package/templates/{turborepo-pandacss → default}/packages/ui/src/skeleton.tsx +0 -0
  215. /package/templates/{turborepo-pandacss → default}/packages/ui/src/sonner.tsx +0 -0
  216. /package/templates/{turborepo-pandacss → default}/packages/ui/src/table.tsx +0 -0
  217. /package/templates/{turborepo-pandacss → default}/packages/ui/src/tabs.tsx +0 -0
  218. /package/templates/{turborepo-pandacss → default}/packages/ui/src/textarea.tsx +0 -0
  219. /package/templates/{turborepo-pandacss → default}/packages/ui/src/tooltip.tsx +0 -0
  220. /package/templates/{turborepo-pandacss → default}/packages/ui/src/typography.tsx +0 -0
  221. /package/templates/{turborepo-pandacss → default}/packages/ui/tsconfig.json +0 -0
  222. /package/templates/{turborepo-pandacss → default}/panda.config.ts +0 -0
  223. /package/templates/{turborepo-pandacss → default}/pnpm-workspace.yaml +0 -0
  224. /package/templates/{turborepo-pandacss → default}/postcss.config.cjs +0 -0
  225. /package/templates/{turborepo-pandacss → default}/prisma/schema.prisma +0 -0
  226. /package/templates/{turborepo-pandacss → default}/public/file.svg +0 -0
  227. /package/templates/{turborepo-pandacss → default}/public/globe.svg +0 -0
  228. /package/templates/{turborepo-pandacss → default}/public/next.svg +0 -0
  229. /package/templates/{turborepo-pandacss → default}/public/vercel.svg +0 -0
  230. /package/templates/{turborepo-pandacss → default}/public/window.svg +0 -0
  231. /package/templates/{turborepo-pandacss → default}/scripts/cli-template-update.ts +0 -0
  232. /package/templates/{turborepo-pandacss → default}/scripts/env-show.ts +0 -0
  233. /package/templates/{turborepo-pandacss → default}/scripts/env.ts +0 -0
  234. /package/templates/{turborepo-pandacss → default}/scripts/init.sh +0 -0
  235. /package/templates/{turborepo-pandacss → default}/scripts/setup-dev.ts +0 -0
  236. /package/templates/{turborepo-pandacss → default}/scripts/template-update.ts +0 -0
  237. /package/templates/{turborepo-pandacss → default}/scripts/worktree/dev.ts +0 -0
  238. /package/templates/{turborepo-pandacss → default}/test/globals.d.ts +0 -0
  239. /package/templates/{turborepo-pandacss → default}/test/setup.ts +0 -0
  240. /package/templates/{turborepo-pandacss → default}/tsconfig.json +0 -0
  241. /package/templates/{turborepo-pandacss → default}/turbo.json +0 -0
  242. /package/templates/{turborepo-pandacss → default}/vitest.config.ts +0 -0
package/README.md CHANGED
@@ -11,7 +11,7 @@ Einja Management Templateを使用したプロジェクトを素早く作成す
11
11
  - 🚀 **新規プロジェクト作成**: `npx create-einja-app my-project` で即座にプロジェクトを作成
12
12
  - 🛠️ **既存プロジェクトセットアップ**: `--setup` オプションで既存プロジェクトにツールを追加
13
13
  - 🔧 **環境ツール統合**: direnv, dotenvx, Volta, Biome, Huskyなどのツールを自動セットアップ
14
- - 🔐 **認証方式選択**: Google OAuth, Credentials, GitHub OAuth, 認証なしから選択可能
14
+ - 🔐 **認証方式選択**: NextAuth.js を使用するか選択可能
15
15
  - 🔄 **対話式プロンプト**: わかりやすいプロンプトで設定を選択
16
16
 
17
17
  ---
@@ -29,9 +29,8 @@ npx create-einja-app my-project
29
29
  対話式プロンプトが表示され、以下の設定を選択できます:
30
30
 
31
31
  - プロジェクト名
32
- - テンプレート(turborepo-pandacss, minimal)
33
- - 認証方式(Google OAuth, Credentials, GitHub OAuth, なし)
34
- - 環境ツール(direnv, dotenvx, Volta)
32
+ - パッケージスコープ
33
+ - 認証機能(NextAuth.js を使用 / なし)
35
34
  - @einja/cli自動セットアップ
36
35
  - Worktree設定カスタマイズ
37
36
 
@@ -47,8 +46,6 @@ npx create-einja-app my-project --skip-git
47
46
  # 依存関係インストールをスキップ
48
47
  npx create-einja-app my-project --skip-install
49
48
 
50
- # テンプレート指定
51
- npx create-einja-app my-project --template turborepo-pandacss
52
49
  ```
53
50
 
54
51
  ### 2. 既存プロジェクトへのツール追加
@@ -80,7 +77,6 @@ npx create-einja-app --setup
80
77
 
81
78
  | オプション | 説明 | デフォルト |
82
79
  |----------|------|----------|
83
- | `--template <name>` | テンプレート名 | `turborepo-pandacss` |
84
80
  | `--skip-git` | Git初期化をスキップ | false |
85
81
  | `--skip-install` | 依存関係インストールをスキップ | false |
86
82
  | `-y, --yes` | 対話プロンプトをスキップ(デフォルト値使用) | false |
package/dist/cli.js CHANGED
@@ -41,52 +41,15 @@ async function promptProjectConfig(defaultProjectName) {
41
41
  return true;
42
42
  }
43
43
  },
44
- {
45
- type: "list",
46
- name: "template",
47
- message: "\u30C6\u30F3\u30D7\u30EC\u30FC\u30C8:",
48
- choices: [
49
- {
50
- name: "turborepo-pandacss (\u30D5\u30EB\u30B9\u30BF\u30C3\u30AF\u7BA1\u7406\u753B\u9762)",
51
- value: "turborepo-pandacss"
52
- },
53
- { name: "minimal (\u6700\u5C0F\u69CB\u6210)", value: "minimal" }
54
- ],
55
- default: "turborepo-pandacss"
56
- },
57
44
  {
58
45
  type: "list",
59
46
  name: "authMethod",
60
- message: "\u8A8D\u8A3C\u65B9\u5F0F:",
47
+ message: "\u8A8D\u8A3C\u6A5F\u80FD:",
61
48
  choices: [
62
- { name: "NextAuth.js (Google OAuth)", value: "google" },
63
- { name: "NextAuth.js (Credentials)", value: "credentials" },
64
- { name: "NextAuth.js (GitHub OAuth)", value: "github" },
65
- { name: "\u306A\u3057", value: "none" }
49
+ { name: "NextAuth.js \u3092\u4F7F\u7528", value: "default" },
50
+ { name: "\u306A\u3057\uFF08\u8A8D\u8A3C\u30D5\u30A1\u30A4\u30EB\u3092\u9664\u5916\uFF09", value: "none" }
66
51
  ],
67
- default: "google"
68
- },
69
- {
70
- type: "checkbox",
71
- name: "tools",
72
- message: "\u74B0\u5883\u30C4\u30FC\u30EB\u3092\u9078\u629E\uFF08\u8907\u6570\u9078\u629E\u53EF\uFF09:",
73
- choices: [
74
- {
75
- name: "direnv\uFF08\u30C7\u30A3\u30EC\u30AF\u30C8\u30EA\u3054\u3068\u306E\u74B0\u5883\u5909\u6570\u7BA1\u7406\uFF09",
76
- value: "direnv",
77
- checked: true
78
- },
79
- {
80
- name: "dotenvx\uFF08.env\u6697\u53F7\u5316\uFF09",
81
- value: "dotenvx",
82
- checked: true
83
- },
84
- {
85
- name: "Volta\uFF08Node.js\u30D0\u30FC\u30B8\u30E7\u30F3\u7BA1\u7406\uFF09",
86
- value: "volta",
87
- checked: true
88
- }
89
- ]
52
+ default: "default"
90
53
  },
91
54
  {
92
55
  type: "confirm",
@@ -101,11 +64,10 @@ async function promptProjectConfig(defaultProjectName) {
101
64
  default: false
102
65
  }
103
66
  ]);
104
- const toolsArray = answers.tools;
105
67
  const tools = {
106
- direnv: toolsArray.includes("direnv"),
107
- dotenvx: toolsArray.includes("dotenvx"),
108
- volta: toolsArray.includes("volta"),
68
+ direnv: true,
69
+ dotenvx: true,
70
+ volta: true,
109
71
  biome: true,
110
72
  husky: true
111
73
  };
@@ -181,7 +143,7 @@ async function promptProjectConfig(defaultProjectName) {
181
143
  return {
182
144
  projectName: answers.projectName,
183
145
  packageScope: answers.packageScope,
184
- template: answers.template,
146
+ template: "default",
185
147
  authMethod: answers.authMethod,
186
148
  tools,
187
149
  setupEinjaCli: answers.setupEinjaCli,
@@ -530,8 +492,8 @@ async function createCommand(projectName, options) {
530
492
  config = {
531
493
  projectName,
532
494
  packageScope: "@repo",
533
- template: options.template || "turborepo-pandacss",
534
- authMethod: "google",
495
+ template: "default",
496
+ authMethod: "default",
535
497
  tools: {
536
498
  direnv: true,
537
499
  dotenvx: true,
@@ -1029,7 +991,7 @@ var packageJsonPath = join10(__dirname2, "../package.json");
1029
991
  var packageJson = JSON.parse(readFileSync4(packageJsonPath, "utf-8"));
1030
992
  var program = new Command();
1031
993
  program.name("create-einja-app").description("CLI tool to create new projects with Einja Management Template").version(packageJson.version);
1032
- program.argument("[project-name]", "Project name").option("--template <template>", "Template to use", "turborepo-pandacss").option("--skip-git", "Skip git initialization").option("--skip-install", "Skip package installation").option("-y, --yes", "Skip interactive prompts").action(
994
+ program.argument("[project-name]", "Project name").option("--skip-git", "Skip git initialization").option("--skip-install", "Skip package installation").option("-y, --yes", "Skip interactive prompts").action(
1033
995
  async (projectName, options) => {
1034
996
  await createCommand(projectName, options);
1035
997
  }
package/dist/cli.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/cli.ts","../src/commands/create.ts","../src/prompts/project.ts","../src/generators/template.ts","../src/utils/fs.ts","../src/utils/logger.ts","../src/generators/post-setup.ts","../src/commands/setup.ts","../src/prompts/setup.ts","../src/generators/tools/direnv.ts","../src/generators/tools/dotenvx.ts","../src/utils/package-json.ts","../src/generators/tools/volta.ts","../src/generators/tools/biome.ts","../src/generators/tools/husky.ts"],"sourcesContent":["import { Command } from \"commander\";\nimport { readFileSync } from \"node:fs\";\nimport { fileURLToPath } from \"node:url\";\nimport { dirname, join } from \"node:path\";\nimport { createCommand } from \"./commands/create.js\";\nimport { setupCommand } from \"./commands/setup.js\";\n\n// package.jsonからバージョン情報を読み込み\nconst __filename = fileURLToPath(import.meta.url);\nconst __dirname = dirname(__filename);\nconst packageJsonPath = join(__dirname, \"../package.json\");\nconst packageJson = JSON.parse(readFileSync(packageJsonPath, \"utf-8\"));\n\nconst program = new Command();\n\nprogram\n .name(\"create-einja-app\")\n .description(\"CLI tool to create new projects with Einja Management Template\")\n .version(packageJson.version);\n\n// createコマンド\nprogram\n .argument(\"[project-name]\", \"Project name\")\n .option(\"--template <template>\", \"Template to use\", \"turborepo-pandacss\")\n .option(\"--skip-git\", \"Skip git initialization\")\n .option(\"--skip-install\", \"Skip package installation\")\n .option(\"-y, --yes\", \"Skip interactive prompts\")\n .action(\n async (\n projectName: string | undefined,\n options: {\n template: string;\n skipGit?: boolean;\n skipInstall?: boolean;\n yes?: boolean;\n }\n ) => {\n await createCommand(projectName, options);\n }\n );\n\n// setupコマンド\nprogram\n .command(\"setup\")\n .description(\"Setup tools for existing project\")\n .action(async () => {\n await setupCommand();\n });\n\nprogram.parse();\n","import { existsSync } from \"node:fs\";\nimport { resolve } from \"node:path\";\nimport ora from \"ora\";\nimport { promptProjectConfig, type ProjectConfig } from \"../prompts/project.js\";\nimport { generateTemplate } from \"../generators/template.js\";\nimport { execPostSetup } from \"../generators/post-setup.js\";\nimport * as logger from \"../utils/logger.js\";\n\n/**\n * CreateOptions型\n * createコマンドのオプション\n */\ninterface CreateOptions {\n template?: string;\n skipGit?: boolean;\n skipInstall?: boolean;\n yes?: boolean;\n}\n\n/**\n * プロジェクト名のバリデーション\n * @param projectName - プロジェクト名\n * @returns エラーメッセージ(問題なければundefined)\n */\nfunction validateProjectName(projectName: string): string | undefined {\n const regex = /^[a-zA-Z][a-zA-Z0-9_-]{0,49}$/;\n if (!regex.test(projectName)) {\n return \"プロジェクト名は英字で始まり、英数字・ハイフン・アンダースコアのみ使用できます(1〜50文字)\";\n }\n return undefined;\n}\n\n/**\n * プロジェクトディレクトリの存在確認\n * @param targetPath - ターゲットパス\n * @returns 存在する場合true\n */\nfunction checkProjectExists(targetPath: string): boolean {\n return existsSync(targetPath);\n}\n\n\n/**\n * createコマンドの実装\n * @param projectName - プロジェクト名(オプション)\n * @param options - コマンドオプション\n */\nexport async function createCommand(\n projectName: string | undefined,\n options: CreateOptions\n): Promise<void> {\n try {\n // プロンプトで設定収集\n let config: ProjectConfig;\n\n if (options.yes && projectName) {\n // --yes オプション: デフォルト値を使用\n const error = validateProjectName(projectName);\n if (error) {\n logger.error(error);\n process.exit(1);\n }\n\n config = {\n projectName,\n packageScope: \"@repo\",\n template: (options.template as \"turborepo-pandacss\" | \"minimal\") || \"turborepo-pandacss\",\n authMethod: \"google\",\n tools: {\n direnv: true,\n dotenvx: true,\n volta: true,\n biome: true,\n husky: true,\n },\n setupEinjaCli: true,\n worktreeConfig: undefined,\n };\n\n logger.info(`プロジェクト名: ${config.projectName}`);\n logger.info(`テンプレート: ${config.template}`);\n logger.info(`認証方式: ${config.authMethod}`);\n } else {\n // 対話式プロンプト\n config = await promptProjectConfig(projectName);\n }\n\n // ターゲットパスの解決\n const targetPath = resolve(process.cwd(), config.projectName);\n\n // プロジェクトディレクトリの存在確認\n if (checkProjectExists(targetPath)) {\n logger.error(`ディレクトリ '${config.projectName}' は既に存在します`);\n logger.info(\"別の名前を指定するか、既存ディレクトリを削除してください\");\n process.exit(1);\n }\n\n // テンプレート展開\n const spinner = ora(\"プロジェクトを作成中...\").start();\n\n try {\n await generateTemplate(config, targetPath);\n spinner.succeed(\"プロジェクトを作成しました\");\n } catch (error) {\n spinner.fail(\"プロジェクトの作成に失敗しました\");\n throw error;\n }\n\n // 生成後セットアップ実行\n await execPostSetup(config, targetPath, {\n skipGit: options.skipGit,\n skipInstall: options.skipInstall,\n });\n } catch (error) {\n logger.error(\"エラーが発生しました:\");\n if (error instanceof Error) {\n logger.error(error.message);\n } else {\n logger.error(String(error));\n }\n process.exit(1);\n }\n}\n","import inquirer from \"inquirer\";\nimport type { ProjectConfig, WorktreeConfig, App } from \"../types/index.js\";\n\nexport type { ProjectConfig, WorktreeConfig, App };\n\n/**\n * プロジェクト作成用プロンプトを実行\n * @param defaultProjectName - デフォルトのプロジェクト名\n * @returns ProjectConfig - プロジェクト設定\n */\nexport async function promptProjectConfig(\n defaultProjectName?: string\n): Promise<ProjectConfig> {\n const answers = await inquirer.prompt([\n {\n type: \"input\",\n name: \"projectName\",\n message: \"プロジェクト名:\",\n default: defaultProjectName || \"my-project\",\n validate: (input: string): boolean | string => {\n // 英数字・ハイフン・アンダースコアのみ許可、先頭は英字、1〜50文字\n const regex = /^[a-zA-Z][a-zA-Z0-9_-]{0,49}$/;\n if (!regex.test(input)) {\n return \"プロジェクト名は英字で始まり、英数字・ハイフン・アンダースコアのみ使用できます(1〜50文字)\";\n }\n return true;\n },\n },\n {\n type: \"input\",\n name: \"packageScope\",\n message: \"パッケージスコープ:\",\n default: \"@repo\",\n validate: (input: string): boolean | string => {\n // @で始まり、英数字・ハイフン・アンダースコアのみ許可\n const regex = /^@[a-zA-Z][a-zA-Z0-9_-]{0,49}$/;\n if (!regex.test(input)) {\n return \"パッケージスコープは@で始まり、英数字・ハイフン・アンダースコアのみ使用できます\";\n }\n return true;\n },\n },\n {\n type: \"list\",\n name: \"template\",\n message: \"テンプレート:\",\n choices: [\n {\n name: \"turborepo-pandacss (フルスタック管理画面)\",\n value: \"turborepo-pandacss\",\n },\n { name: \"minimal (最小構成)\", value: \"minimal\" },\n ],\n default: \"turborepo-pandacss\",\n },\n {\n type: \"list\",\n name: \"authMethod\",\n message: \"認証方式:\",\n choices: [\n { name: \"NextAuth.js (Google OAuth)\", value: \"google\" },\n { name: \"NextAuth.js (Credentials)\", value: \"credentials\" },\n { name: \"NextAuth.js (GitHub OAuth)\", value: \"github\" },\n { name: \"なし\", value: \"none\" },\n ],\n default: \"google\",\n },\n {\n type: \"checkbox\",\n name: \"tools\",\n message: \"環境ツールを選択(複数選択可):\",\n choices: [\n {\n name: \"direnv(ディレクトリごとの環境変数管理)\",\n value: \"direnv\",\n checked: true,\n },\n {\n name: \"dotenvx(.env暗号化)\",\n value: \"dotenvx\",\n checked: true,\n },\n {\n name: \"Volta(Node.jsバージョン管理)\",\n value: \"volta\",\n checked: true,\n },\n ],\n },\n {\n type: \"confirm\",\n name: \"setupEinjaCli\",\n message: \"@einja/cli を自動セットアップしますか?\",\n default: true,\n },\n {\n type: \"confirm\",\n name: \"customizeWorktree\",\n message: \"Worktree設定をカスタマイズしますか?\",\n default: false,\n },\n ]);\n\n // ツール選択を boolean フラグに変換\n const toolsArray = answers.tools as string[];\n const tools = {\n direnv: toolsArray.includes(\"direnv\"),\n dotenvx: toolsArray.includes(\"dotenvx\"),\n volta: toolsArray.includes(\"volta\"),\n biome: true,\n husky: true,\n };\n\n let worktreeConfig: WorktreeConfig | undefined;\n\n // Worktree設定カスタマイズ\n if (answers.customizeWorktree) {\n const worktreeAnswers = await inquirer.prompt([\n {\n type: \"input\",\n name: \"postgresPort\",\n message: \"PostgreSQLポート番号:\",\n default: \"25432\",\n validate: (input: string): boolean | string => {\n const port = Number.parseInt(input, 10);\n if (Number.isNaN(port) || port < 1024 || port > 65535) {\n return \"ポート番号は1024〜65535の範囲で指定してください\";\n }\n return true;\n },\n },\n {\n type: \"input\",\n name: \"containerName\",\n message: \"Dockerコンテナ名:\",\n default: `${answers.projectName}-postgres`,\n },\n {\n type: \"input\",\n name: \"appId\",\n message: \"アプリケーションID:\",\n default: \"web\",\n },\n {\n type: \"input\",\n name: \"portRangeStart\",\n message: \"アプリポート範囲開始:\",\n default: \"3000\",\n validate: (input: string): boolean | string => {\n const port = Number.parseInt(input, 10);\n if (Number.isNaN(port) || port < 1024 || port > 65535) {\n return \"ポート番号は1024〜65535の範囲で指定してください\";\n }\n return true;\n },\n },\n {\n type: \"input\",\n name: \"rangeSize\",\n message: \"ポート範囲サイズ:\",\n default: \"1000\",\n validate: (input: string): boolean | string => {\n const size = Number.parseInt(input, 10);\n if (Number.isNaN(size) || size < 1 || size > 10000) {\n return \"範囲サイズは1〜10000の範囲で指定してください\";\n }\n return true;\n },\n },\n ]);\n\n worktreeConfig = {\n postgres: {\n port: Number.parseInt(worktreeAnswers.postgresPort, 10),\n containerName: worktreeAnswers.containerName,\n },\n apps: [\n {\n id: worktreeAnswers.appId,\n portRangeStart: Number.parseInt(worktreeAnswers.portRangeStart, 10),\n rangeSize: Number.parseInt(worktreeAnswers.rangeSize, 10),\n },\n ],\n };\n }\n\n return {\n projectName: answers.projectName,\n packageScope: answers.packageScope,\n template: answers.template,\n authMethod: answers.authMethod,\n tools,\n setupEinjaCli: answers.setupEinjaCli,\n worktreeConfig,\n };\n}\n","import fsExtra from \"fs-extra\";\nconst { copySync, readFileSync, writeFileSync, existsSync, removeSync } = fsExtra;\nimport { glob } from \"glob\";\nimport { dirname, join, relative } from \"node:path\";\nimport { fileURLToPath } from \"node:url\";\nimport type { ProjectConfig } from \"../prompts/project.js\";\nimport { ensureDir } from \"../utils/fs.js\";\nimport * as logger from \"../utils/logger.js\";\n\n/**\n * TemplateVariables型\n * テンプレート変数(プレースホルダー置換用)\n */\nexport interface TemplateVariables {\n projectName: string;\n packageName: string;\n description: string;\n}\n\n/**\n * テンプレートディレクトリのパスを取得\n * @param templateName - テンプレート名\n * @returns テンプレートディレクトリパス\n */\nfunction getTemplatePath(templateName: string): string {\n const __filename = fileURLToPath(import.meta.url);\n const __dirname = dirname(__filename);\n\n // バンドル後(dist/cli.js)とソース実行(src/generators/template.ts)の両方に対応\n // dist/cli.js -> ../templates/ (1階層上)\n // src/generators/template.ts -> ../../templates/ (2階層上)\n const distPath = join(__dirname, \"../templates\", templateName);\n const srcPath = join(__dirname, \"../../templates\", templateName);\n\n if (existsSync(distPath)) {\n return distPath;\n }\n if (existsSync(srcPath)) {\n return srcPath;\n }\n\n // どちらも存在しない場合はdistPathを返す(エラーメッセージ用)\n return distPath;\n}\n\n/**\n * 認証方式に応じた除外パターンを取得\n * @param authMethod - 認証方式\n * @returns 除外パターン配列\n */\nfunction getAuthExcludePatterns(authMethod: string): string[] {\n if (authMethod === \"none\") {\n return [\n \"**/api/auth/**\",\n \"**/packages/auth/**\",\n \"**/signin/**\",\n \"**/signup/**\",\n ];\n }\n return [];\n}\n\n/**\n * ファイル内容のプレースホルダー変数を置換\n * @param content - ファイル内容\n * @param variables - 置換する変数\n * @returns 置換後の内容\n */\nfunction replacePlaceholders(\n content: string,\n variables: TemplateVariables\n): string {\n let result = content;\n\n // {{projectName}} の置換\n result = result.replaceAll(\"{{projectName}}\", variables.projectName);\n\n // {{packageName}}/ の置換(長いパターンを先に置換)\n result = result.replaceAll(\"{{packageName}}/\", `${variables.packageName}/`);\n\n // {{packageName}} の置換\n result = result.replaceAll(\"{{packageName}}\", variables.packageName);\n\n // {{description}} の置換\n result = result.replaceAll(\"{{description}}\", variables.description);\n\n // @repo/ の置換(パッケージスコープ)\n result = result.replaceAll(\"@repo/\", `${variables.packageName}/`);\n\n return result;\n}\n\n/**\n * ファイルの変数置換処理\n * @param filePath - ファイルパス\n * @param variables - 置換する変数\n */\nfunction processFileVariables(\n filePath: string,\n variables: TemplateVariables\n): void {\n // バイナリファイルは処理しない\n const binaryExtensions = [\".png\", \".jpg\", \".jpeg\", \".gif\", \".ico\", \".woff\", \".woff2\", \".ttf\", \".eot\"];\n if (binaryExtensions.some((ext) => filePath.endsWith(ext))) {\n return;\n }\n\n try {\n const content = readFileSync(filePath, \"utf-8\");\n const replaced = replacePlaceholders(content, variables);\n\n if (content !== replaced) {\n writeFileSync(filePath, replaced, \"utf-8\");\n }\n } catch (error) {\n // 読み込みに失敗した場合はスキップ(バイナリファイル等)\n logger.warn(`変数置換をスキップ: ${filePath}`);\n }\n}\n\n/**\n * .templateファイルのリネーム処理\n * @param targetPath - ターゲットディレクトリパス\n */\nfunction renameTemplateFiles(targetPath: string): void {\n const templateFiles = glob.sync(\"**/*.template\", {\n cwd: targetPath,\n absolute: true,\n dot: true,\n });\n\n for (const file of templateFiles) {\n const newPath = file.replace(/\\.template$/, \"\");\n copySync(file, newPath);\n removeSync(file);\n }\n}\n\n/**\n * 認証方式に応じたファイル除外処理\n * @param targetPath - ターゲットディレクトリパス\n * @param authMethod - 認証方式\n */\nfunction excludeAuthFiles(targetPath: string, authMethod: string): void {\n const excludePatterns = getAuthExcludePatterns(authMethod);\n\n if (excludePatterns.length === 0) {\n return;\n }\n\n logger.info(\"認証方式に応じたファイルを除外中...\");\n\n for (const pattern of excludePatterns) {\n const files = glob.sync(pattern, {\n cwd: targetPath,\n absolute: true,\n dot: true,\n });\n\n for (const file of files) {\n removeSync(file);\n }\n }\n}\n\n/**\n * テンプレートを展開\n * @param config - プロジェクト設定\n * @param targetPath - ターゲットディレクトリパス\n */\nexport async function generateTemplate(\n config: ProjectConfig,\n targetPath: string\n): Promise<void> {\n const templatePath = getTemplatePath(config.template);\n\n // テンプレートディレクトリの存在確認\n if (!existsSync(templatePath)) {\n throw new Error(`テンプレートが見つかりません: ${config.template}`);\n }\n\n logger.info(\"テンプレートをコピー中...\");\n\n // ターゲットディレクトリの作成\n await ensureDir(targetPath);\n\n // テンプレートファイルをコピー\n copySync(templatePath, targetPath, {\n filter: (src: string): boolean => {\n const relativePath = relative(templatePath, src);\n\n // 除外パターン(ディレクトリ名やファイル名として完全一致するもの)\n const excludePatterns = [\n \"node_modules\",\n \".git\",\n \".next\",\n \".turbo\",\n \"out\",\n \"dist\",\n \"logs\",\n \".env\",\n \".env.local\",\n \".DS_Store\",\n \"Thumbs.db\",\n \"coverage\",\n ];\n\n // ファイル拡張子パターン(*.log など)\n const excludeExtensions = [\".log\"];\n\n // パスセグメントに分割(/ または \\ で分割)\n const pathSegments = relativePath.split(/[/\\\\]/);\n\n // パスセグメント単位で完全一致チェック\n // これにより \"out\" は \"out/\" ディレクトリにマッチするが\n // \"logout-button.tsx\" にはマッチしない\n const matchesExcludePattern = excludePatterns.some((pattern) =>\n pathSegments.includes(pattern)\n );\n\n // 拡張子チェック\n const matchesExtension = excludeExtensions.some((ext) =>\n relativePath.endsWith(ext)\n );\n\n return !matchesExcludePattern && !matchesExtension;\n },\n });\n\n // 認証方式に応じたファイル除外\n excludeAuthFiles(targetPath, config.authMethod);\n\n // .templateファイルのリネーム\n renameTemplateFiles(targetPath);\n\n // 変数置換\n logger.info(\"プレースホルダー変数を置換中...\");\n\n const variables: TemplateVariables = {\n projectName: config.projectName,\n packageName: config.packageScope,\n description: `${config.projectName} - Einja Management Template`,\n };\n\n const allFiles = glob.sync(\"**/*\", {\n cwd: targetPath,\n absolute: true,\n nodir: true,\n dot: true,\n });\n\n for (const file of allFiles) {\n processFileVariables(file, variables);\n }\n\n logger.success(\"テンプレート展開完了\");\n}\n","import { existsSync, readFileSync, writeFileSync, appendFileSync, mkdirSync } from \"node:fs\";\nimport { join, dirname } from \"node:path\";\nimport type { ConflictStrategy } from \"../types/index.js\";\n\n/**\n * 競合戦略に基づいてファイルを書き込む\n */\nexport function writeWithStrategy(\n filePath: string,\n content: string,\n strategy: ConflictStrategy\n): boolean {\n const exists = existsSync(filePath);\n\n if (!exists) {\n ensureDir(dirname(filePath));\n writeFileSync(filePath, content, \"utf-8\");\n return true;\n }\n\n switch (strategy) {\n case \"overwrite\": {\n writeFileSync(filePath, content, \"utf-8\");\n return true;\n }\n\n case \"merge\": {\n const existingContent = readFileSync(filePath, \"utf-8\");\n const mergedContent = mergeContent(existingContent, content);\n writeFileSync(filePath, mergedContent, \"utf-8\");\n return true;\n }\n\n case \"skip\": {\n return false;\n }\n\n default: {\n const _exhaustiveCheck: never = strategy;\n throw new Error(`Unknown strategy: ${_exhaustiveCheck}`);\n }\n }\n}\n\n/**\n * 既存コンテンツと新規コンテンツをマージする\n */\nfunction mergeContent(existing: string, newContent: string): string {\n if (existing.includes(newContent)) {\n return existing;\n }\n return `${existing}\\n${newContent}`;\n}\n\n/**\n * ディレクトリが存在しない場合は作成する\n */\nexport function ensureDir(dirPath: string): void {\n if (!existsSync(dirPath)) {\n mkdirSync(dirPath, { recursive: true });\n }\n}\n\n/**\n * .gitignoreに行を追加する\n */\nexport function appendToGitignore(targetDir: string, line: string): void {\n const gitignorePath = join(targetDir, \".gitignore\");\n\n if (!existsSync(gitignorePath)) {\n writeFileSync(gitignorePath, `${line}\\n`, \"utf-8\");\n return;\n }\n\n const content = readFileSync(gitignorePath, \"utf-8\");\n if (content.includes(line)) {\n return;\n }\n\n appendFileSync(gitignorePath, `\\n${line}\\n`, \"utf-8\");\n}\n\n/**\n * ファイルが存在するか確認する\n */\nexport function fileExists(filePath: string): boolean {\n return existsSync(filePath);\n}\n","import chalk from \"chalk\";\n\n/**\n * 情報メッセージを出力\n * @param message - メッセージ\n */\nexport function info(message: string): void {\n console.log(chalk.blue(\"ℹ\"), message);\n}\n\n/**\n * 成功メッセージを出力(緑色)\n * @param message - メッセージ\n */\nexport function success(message: string): void {\n console.log(chalk.green(\"✔\"), message);\n}\n\n/**\n * 警告メッセージを出力(黄色)\n * @param message - メッセージ\n */\nexport function warn(message: string): void {\n console.log(chalk.yellow(\"⚠\"), message);\n}\n\n/**\n * エラーメッセージを出力(赤色)\n * @param message - メッセージ\n */\nexport function error(message: string): void {\n console.error(chalk.red(\"✖\"), message);\n}\n","import { execa, execaSync } from \"execa\";\nimport chalk from \"chalk\";\nimport inquirer from \"inquirer\";\nimport ora from \"ora\";\nimport type { ProjectConfig } from \"../types/index.js\";\nimport * as logger from \"../utils/logger.js\";\n\n/**\n * PostSetupOptions型\n * 生成後セットアップのオプション\n */\nexport interface PostSetupOptions {\n skipGit?: boolean;\n skipInstall?: boolean;\n}\n\n/**\n * direnvコマンドが利用可能かチェック\n * @returns direnvコマンドが利用可能な場合true\n */\nfunction isDirenvAvailable(): boolean {\n try {\n execaSync(\"which\", [\"direnv\"]);\n return true;\n } catch {\n return false;\n }\n}\n\n/**\n * direnv allowの確認プロンプトを表示し、実行する\n * @param targetPath - プロジェクトディレクトリ\n */\nasync function promptAndExecuteDirenvAllow(targetPath: string): Promise<void> {\n try {\n const { shouldAllow } = await inquirer.prompt([\n {\n type: \"confirm\",\n name: \"shouldAllow\",\n message: \"direnv allow を実行しますか?(環境変数を有効化します)\",\n default: true,\n },\n ]);\n\n if (shouldAllow) {\n try {\n await execa(\"direnv\", [\"allow\"], { cwd: targetPath });\n logger.success(\"direnv allow を実行しました\");\n } catch (error) {\n logger.warn(\"direnv allow の実行に失敗しました\");\n logger.info(\"後で手動で 'direnv allow' を実行してください\");\n }\n } else {\n logger.info(\"direnv allow をスキップしました\");\n logger.info(\"後で手動で 'direnv allow' を実行してください\");\n }\n } catch (error) {\n logger.info(\"direnv allow をスキップしました\");\n }\n}\n\n/**\n * 完了メッセージを表示\n * @param config - プロジェクト設定\n */\nfunction printCompletionMessage(config: ProjectConfig): void {\n console.log();\n logger.success(\"プロジェクトの作成が完了しました!\");\n console.log();\n console.log(chalk.bold(\"次のステップ:\"));\n console.log();\n console.log(chalk.cyan(` cd ${config.projectName}`));\n console.log(chalk.cyan(\" docker-compose up -d postgres\"));\n console.log(chalk.cyan(\" pnpm dev\"));\n console.log();\n console.log(chalk.gray(\"開発サーバー: http://localhost:3000\"));\n console.log();\n console.log(chalk.gray(\"詳細は README.md をご確認ください。\"));\n console.log();\n}\n\n/**\n * 生成後セットアップを実行\n * @param config - プロジェクト設定\n * @param targetPath - プロジェクトディレクトリ\n * @param options - セットアップオプション\n */\nexport async function execPostSetup(\n config: ProjectConfig,\n targetPath: string,\n options: PostSetupOptions\n): Promise<void> {\n const { skipGit, skipInstall } = options;\n\n // Git初期化\n if (!skipGit) {\n const gitSpinner = ora(\"Gitリポジトリを初期化中...\").start();\n try {\n await execa(\"git\", [\"init\"], { cwd: targetPath });\n await execa(\"git\", [\"add\", \".\"], { cwd: targetPath });\n await execa(\"git\", [\"commit\", \"-m\", \"Initial commit\"], { cwd: targetPath });\n gitSpinner.succeed(\"Gitリポジトリを初期化しました\");\n } catch (error) {\n gitSpinner.fail(\"Gitリポジトリの初期化に失敗しました\");\n logger.warn(\"後で手動で 'git init' を実行してください\");\n }\n }\n\n // 依存関係インストール\n if (!skipInstall) {\n const installSpinner = ora(\"依存関係をインストール中...\").start();\n try {\n await execa(\"pnpm\", [\"install\"], { cwd: targetPath });\n installSpinner.succeed(\"依存関係をインストールしました\");\n\n // Prismaクライアント生成\n const prismaSpinner = ora(\"Prismaクライアントを生成中...\").start();\n try {\n await execa(\"pnpm\", [\"db:generate\"], { cwd: targetPath });\n prismaSpinner.succeed(\"Prismaクライアントを生成しました\");\n } catch (error) {\n prismaSpinner.fail(\"Prismaクライアントの生成に失敗しました\");\n logger.warn(\"後で手動で 'pnpm db:generate' を実行してください\");\n }\n } catch (error) {\n installSpinner.fail(\"依存関係のインストールに失敗しました\");\n logger.warn(\"後で手動で 'pnpm install' を実行してください\");\n }\n }\n\n // direnv allow(direnvが有効で、コマンドが利用可能な場合)\n if (config.tools.direnv && isDirenvAvailable()) {\n await promptAndExecuteDirenvAllow(targetPath);\n }\n\n // @einja/cli init\n if (config.setupEinjaCli) {\n const einjaSpinner = ora(\"@einja/cli を初期化中...\").start();\n try {\n await execa(\"npx\", [\"@einja/cli\", \"init\"], { cwd: targetPath });\n einjaSpinner.succeed(\"@einja/cli を初期化しました\");\n } catch (error) {\n einjaSpinner.fail(\"@einja/cli の初期化に失敗しました\");\n logger.warn(\"後で手動で 'npx @einja/cli init' を実行してください\");\n }\n }\n\n // 完了メッセージ表示\n printCompletionMessage(config);\n}\n","import { existsSync } from \"node:fs\";\nimport { join } from \"node:path\";\nimport ora from \"ora\";\nimport { promptSetupConfig } from \"../prompts/setup.js\";\nimport {\n setupDirenv,\n setupDotenvx,\n setupVolta,\n setupBiome,\n setupHusky,\n promptDirenvAllow,\n} from \"../generators/tools/index.js\";\nimport type { ToolSetupOptions } from \"../types/index.js\";\nimport * as logger from \"../utils/logger.js\";\n\n/**\n * setupコマンド - 既存プロジェクトへのツール追加\n *\n * US-002: 既存プロジェクトへの環境ツール追加\n * AC-002-1: `npx create-einja-app --setup` で対話式プロンプトが表示される\n * AC-002-2: 既存の設定ファイルがある場合、マージ・上書き・スキップを選択できる\n * AC-002-3: 選択したツールのみがセットアップされる\n * AC-002-4: 既存ファイルを破壊せずにツールが追加される(マージモード時)\n */\nexport async function setupCommand(): Promise<void> {\n const targetDir = process.cwd();\n\n // 1. プロジェクトディレクトリ確認(package.json存在確認)\n const packageJsonPath = join(targetDir, \"package.json\");\n if (!existsSync(packageJsonPath)) {\n logger.error(\"エラー: package.jsonが見つかりません\");\n logger.info(\"このコマンドは既存のプロジェクトディレクトリで実行してください\");\n process.exit(1);\n }\n\n logger.info(\"既存プロジェクトへのツール追加を開始します\");\n logger.info(\"\");\n\n // 2. プロンプトで設定収集\n const config = await promptSetupConfig();\n\n logger.info(\"\");\n logger.info(\"セットアップを開始します...\");\n logger.info(\"\");\n\n const options: ToolSetupOptions = {\n targetDir,\n conflictStrategy: config.conflictStrategy,\n };\n\n // 3. 選択されたツールのセットアップ\n let setupCount = 0;\n\n if (config.tools.direnv) {\n const spin = ora(\"direnv をセットアップしています...\").start();\n try {\n setupDirenv(options);\n spin.succeed(\"direnv セットアップ完了\");\n setupCount++;\n } catch (error) {\n spin.fail(\"direnv セットアップ失敗\");\n logger.error(\n error instanceof Error ? error.message : \"予期しないエラーが発生しました\"\n );\n }\n }\n\n if (config.tools.dotenvx) {\n const spin = ora(\"dotenvx をセットアップしています...\").start();\n try {\n setupDotenvx(options);\n spin.succeed(\"dotenvx セットアップ完了\");\n setupCount++;\n } catch (error) {\n spin.fail(\"dotenvx セットアップ失敗\");\n logger.error(\n error instanceof Error ? error.message : \"予期しないエラーが発生しました\"\n );\n }\n }\n\n if (config.tools.volta) {\n const spin = ora(\"Volta をセットアップしています...\").start();\n try {\n setupVolta(options);\n spin.succeed(\"Volta セットアップ完了\");\n setupCount++;\n } catch (error) {\n spin.fail(\"Volta セットアップ失敗\");\n logger.error(\n error instanceof Error ? error.message : \"予期しないエラーが発生しました\"\n );\n }\n }\n\n if (config.tools.biome) {\n const spin = ora(\"Biome をセットアップしています...\").start();\n try {\n setupBiome(options);\n spin.succeed(\"Biome セットアップ完了\");\n setupCount++;\n } catch (error) {\n spin.fail(\"Biome セットアップ失敗\");\n logger.error(\n error instanceof Error ? error.message : \"予期しないエラーが発生しました\"\n );\n }\n }\n\n if (config.tools.husky) {\n const spin = ora(\"Husky をセットアップしています...\").start();\n try {\n setupHusky(options);\n spin.succeed(\"Husky セットアップ完了\");\n setupCount++;\n } catch (error) {\n spin.fail(\"Husky セットアップ失敗\");\n logger.error(\n error instanceof Error ? error.message : \"予期しないエラーが発生しました\"\n );\n }\n }\n\n logger.info(\"\");\n\n // 4. direnv allowの確認プロンプト(direnvがセットアップされた場合のみ)\n if (config.tools.direnv) {\n await promptDirenvAllow(targetDir);\n logger.info(\"\");\n }\n\n // 5. 完了メッセージ\n logger.success(`✅ セットアップが完了しました!(${setupCount}個のツール)`);\n logger.info(\"\");\n logger.info(\"次のステップ:\");\n\n if (config.tools.direnv) {\n logger.info(\" 1. .envrc を編集して環境変数を設定\");\n logger.info(\" 2. direnv allow を実行(まだの場合)\");\n }\n\n if (config.tools.dotenvx) {\n logger.info(\" - .env.example をコピーして .env を作成\");\n logger.info(\" - 必要に応じて pnpm env:encrypt で暗号化\");\n }\n\n if (config.tools.biome) {\n logger.info(\" - pnpm lint でコードをチェック\");\n logger.info(\" - pnpm format:fix でフォーマット\");\n }\n\n if (config.tools.husky) {\n logger.info(\" - pnpm install でHuskyフックをインストール\");\n }\n\n logger.info(\"\");\n logger.success(\"開発を開始できます!\");\n}\n","import inquirer from \"inquirer\";\n\n/**\n * SetupConfig型\n * 既存プロジェクトへのツール追加設定\n */\nexport interface SetupConfig {\n tools: {\n direnv: boolean;\n dotenvx: boolean;\n volta: boolean;\n biome: boolean;\n husky: boolean;\n };\n conflictStrategy: \"merge\" | \"overwrite\" | \"skip\";\n}\n\n/**\n * セットアップ用プロンプトを実行\n * @returns SetupConfig - セットアップ設定\n */\nexport async function promptSetupConfig(): Promise<SetupConfig> {\n const answers = await inquirer.prompt([\n {\n type: \"checkbox\",\n name: \"tools\",\n message: \"セットアップするツールを選択(複数選択可):\",\n choices: [\n {\n name: \"direnv(ディレクトリごとの環境変数管理)\",\n value: \"direnv\",\n checked: true,\n },\n {\n name: \"dotenvx(.env暗号化)\",\n value: \"dotenvx\",\n checked: true,\n },\n {\n name: \"Volta(Node.jsバージョン管理)\",\n value: \"volta\",\n checked: true,\n },\n {\n name: \"Biome(Linter / Formatter)\",\n value: \"biome\",\n checked: false,\n },\n {\n name: \"Husky + lint-staged(Git hooks)\",\n value: \"husky\",\n checked: false,\n },\n ],\n },\n {\n type: \"list\",\n name: \"conflictStrategy\",\n message: \"既存ファイルがある場合の動作:\",\n choices: [\n {\n name: \"マージ(既存設定を保持しつつ追加)\",\n value: \"merge\",\n },\n {\n name: \"上書き\",\n value: \"overwrite\",\n },\n {\n name: \"スキップ\",\n value: \"skip\",\n },\n ],\n default: \"merge\",\n },\n ]);\n\n // ツール選択を boolean フラグに変換\n const toolsArray = answers.tools as string[];\n const tools = {\n direnv: toolsArray.includes(\"direnv\"),\n dotenvx: toolsArray.includes(\"dotenvx\"),\n volta: toolsArray.includes(\"volta\"),\n biome: toolsArray.includes(\"biome\"),\n husky: toolsArray.includes(\"husky\"),\n };\n\n return {\n tools,\n conflictStrategy: answers.conflictStrategy,\n };\n}\n","import { join } from \"node:path\";\nimport { execSync } from \"node:child_process\";\nimport inquirer from \"inquirer\";\nimport type { ToolSetupOptions } from \"../../types/index.js\";\nimport { writeWithStrategy, appendToGitignore } from \"../../utils/fs.js\";\nimport * as logger from \"../../utils/logger.js\";\n\nconst ENVRC_CONTENT = `# direnv configuration\n# Load .env if it exists\ndotenv_if_exists\n\n# Allow local overrides\ndotenv_if_exists .env.local\n`;\n\nconst ENVRC_EXAMPLE_CONTENT = `# Example direnv configuration\n# Copy this file to .envrc and run 'direnv allow'\n\n# Load environment variables from .env\ndotenv_if_exists\n\n# Load local overrides\ndotenv_if_exists .env.local\n`;\n\n/**\n * direnvのセットアップを実行する\n *\n * AC-003-1: .envrc ファイルが生成される\n * AC-003-2: .envrc.example ファイルが生成される\n * AC-003-3: .gitignore に .envrc が追加される\n */\nexport function setupDirenv(options: ToolSetupOptions): void {\n const { targetDir, conflictStrategy } = options;\n\n const envrcPath = join(targetDir, \".envrc\");\n const envrcExamplePath = join(targetDir, \".envrc.example\");\n\n writeWithStrategy(envrcPath, ENVRC_CONTENT, conflictStrategy);\n\n writeWithStrategy(envrcExamplePath, ENVRC_EXAMPLE_CONTENT, conflictStrategy);\n\n appendToGitignore(targetDir, \".envrc\");\n}\n\n/**\n * direnv allowの確認プロンプトを表示し、実行する\n *\n * AC-003-4: 確認後 `direnv allow` が実行される\n *\n * @param targetDir - ターゲットディレクトリ\n */\nexport async function promptDirenvAllow(targetDir: string): Promise<void> {\n try {\n const { shouldAllow } = await inquirer.prompt([\n {\n type: \"confirm\",\n name: \"shouldAllow\",\n message: \"direnv allow を実行しますか?(環境変数を有効化します)\",\n default: true,\n },\n ]);\n\n if (shouldAllow) {\n try {\n execSync(\"direnv allow\", { cwd: targetDir, stdio: \"inherit\" });\n logger.success(\"direnv allow を実行しました\");\n } catch (error) {\n logger.warn(\"direnv allow の実行に失敗しました\");\n logger.info(\"後で手動で 'direnv allow' を実行してください\");\n }\n } else {\n logger.info(\"direnv allow をスキップしました\");\n logger.info(\"後で手動で 'direnv allow' を実行してください\");\n }\n } catch (error) {\n // プロンプトがキャンセルされた場合など\n logger.info(\"direnv allow をスキップしました\");\n }\n}\n","import { join } from \"node:path\";\nimport type { ToolSetupOptions } from \"../../types/index.js\";\nimport { writeWithStrategy } from \"../../utils/fs.js\";\nimport { addDependencies, addScripts } from \"../../utils/package-json.js\";\n\nconst ENV_EXAMPLE_CONTENT = `# Environment variables template\n# Copy this file to .env and fill in the values\n\n# Database\nDATABASE_URL=\"postgresql://user:password@localhost:25432/dbname\"\n\n# NextAuth\nNEXTAUTH_URL=\"http://localhost:3000\"\nNEXTAUTH_SECRET=\"your-secret-here\"\n\n# OAuth (if using)\n# GOOGLE_CLIENT_ID=\"\"\n# GOOGLE_CLIENT_SECRET=\"\"\n# GITHUB_CLIENT_ID=\"\"\n# GITHUB_CLIENT_SECRET=\"\"\n`;\n\n/**\n * dotenvxのセットアップを実行する\n *\n * AC-004-1: package.jsonに依存関係が追加される\n * AC-004-2: npm scriptsにdotenvxコマンドが追加される\n * AC-004-3: .env.example が生成される\n */\nexport function setupDotenvx(options: ToolSetupOptions): void {\n const { targetDir, conflictStrategy } = options;\n\n addDependencies(targetDir, {\n \"@dotenvx/dotenvx\": \"^1.29.0\",\n });\n\n addScripts(targetDir, {\n \"env:encrypt\": \"dotenvx encrypt\",\n \"env:decrypt\": \"dotenvx decrypt\",\n });\n\n const envExamplePath = join(targetDir, \".env.example\");\n writeWithStrategy(envExamplePath, ENV_EXAMPLE_CONTENT, conflictStrategy);\n}\n","import { readFileSync, writeFileSync } from \"node:fs\";\nimport { join } from \"node:path\";\nimport { fileExists } from \"./fs.js\";\n\ntype PackageJson = {\n name?: string;\n version?: string;\n scripts?: Record<string, string>;\n dependencies?: Record<string, string>;\n devDependencies?: Record<string, string>;\n volta?: {\n node?: string;\n pnpm?: string;\n };\n \"lint-staged\"?: Record<string, string | string[]>;\n [key: string]: unknown;\n};\n\n/**\n * package.jsonを読み込む\n */\nexport function readPackageJson(targetDir: string): PackageJson {\n const packageJsonPath = join(targetDir, \"package.json\");\n\n if (!fileExists(packageJsonPath)) {\n return {};\n }\n\n const content = readFileSync(packageJsonPath, \"utf-8\");\n return JSON.parse(content) as PackageJson;\n}\n\n/**\n * package.jsonに書き込む\n */\nexport function writePackageJson(targetDir: string, data: PackageJson): void {\n const packageJsonPath = join(targetDir, \"package.json\");\n const content = JSON.stringify(data, null, 2);\n writeFileSync(packageJsonPath, `${content}\\n`, \"utf-8\");\n}\n\n/**\n * package.jsonにスクリプトを追加する\n */\nexport function addScripts(\n targetDir: string,\n scripts: Record<string, string>\n): void {\n const pkg = readPackageJson(targetDir);\n pkg.scripts = { ...pkg.scripts, ...scripts };\n writePackageJson(targetDir, pkg);\n}\n\n/**\n * package.jsonに依存関係を追加する\n */\nexport function addDependencies(\n targetDir: string,\n dependencies: Record<string, string>,\n dev = false\n): void {\n const pkg = readPackageJson(targetDir);\n\n if (dev) {\n pkg.devDependencies = { ...pkg.devDependencies, ...dependencies };\n } else {\n pkg.dependencies = { ...pkg.dependencies, ...dependencies };\n }\n\n writePackageJson(targetDir, pkg);\n}\n\n/**\n * package.jsonにVoltaフィールドを追加する\n */\nexport function addVoltaField(\n targetDir: string,\n nodeVersion: string,\n pnpmVersion: string\n): void {\n const pkg = readPackageJson(targetDir);\n pkg.volta = {\n node: nodeVersion,\n pnpm: pnpmVersion,\n };\n writePackageJson(targetDir, pkg);\n}\n\n/**\n * package.jsonにlint-staged設定を追加する\n */\nexport function addLintStaged(\n targetDir: string,\n config: Record<string, string | string[]>\n): void {\n const pkg = readPackageJson(targetDir);\n pkg[\"lint-staged\"] = { ...pkg[\"lint-staged\"], ...config };\n writePackageJson(targetDir, pkg);\n}\n","import { join } from \"node:path\";\nimport type { ToolSetupOptions } from \"../../types/index.js\";\nimport { writeWithStrategy } from \"../../utils/fs.js\";\nimport { addVoltaField } from \"../../utils/package-json.js\";\n\nconst NODE_VERSION = \"22.16.0\";\nconst PNPM_VERSION = \"9.15.0\";\n\nconst NODE_VERSION_CONTENT = `${NODE_VERSION}\n`;\n\n/**\n * Voltaのセットアップを実行する\n *\n * AC-005-1: package.jsonにvoltaフィールドが追加される\n * AC-005-2: .node-version ファイルが生成される\n */\nexport function setupVolta(options: ToolSetupOptions): void {\n const { targetDir, conflictStrategy } = options;\n\n addVoltaField(targetDir, NODE_VERSION, PNPM_VERSION);\n\n const nodeVersionPath = join(targetDir, \".node-version\");\n writeWithStrategy(nodeVersionPath, NODE_VERSION_CONTENT, conflictStrategy);\n}\n","import { join } from \"node:path\";\nimport type { ToolSetupOptions } from \"../../types/index.js\";\nimport { writeWithStrategy, ensureDir } from \"../../utils/fs.js\";\nimport { addDependencies, addScripts } from \"../../utils/package-json.js\";\n\nconst BIOME_CONFIG = `{\n \"$schema\": \"https://biomejs.dev/schemas/1.9.4/schema.json\",\n \"vcs\": {\n \"enabled\": true,\n \"clientKind\": \"git\",\n \"useIgnoreFile\": true\n },\n \"files\": {\n \"ignoreUnknown\": false,\n \"ignore\": [\"node_modules\", \"dist\", \".next\", \"out\", \"build\", \"coverage\"]\n },\n \"formatter\": {\n \"enabled\": true,\n \"indentStyle\": \"space\",\n \"indentWidth\": 2,\n \"lineEnding\": \"lf\",\n \"lineWidth\": 100\n },\n \"organizeImports\": {\n \"enabled\": true\n },\n \"linter\": {\n \"enabled\": true,\n \"rules\": {\n \"recommended\": true\n }\n },\n \"javascript\": {\n \"formatter\": {\n \"quoteStyle\": \"double\",\n \"trailingCommas\": \"es5\",\n \"semicolons\": \"always\",\n \"arrowParentheses\": \"always\"\n }\n }\n}\n`;\n\nconst VSCODE_SETTINGS = `{\n \"editor.defaultFormatter\": \"biomejs.biome\",\n \"editor.formatOnSave\": true,\n \"editor.codeActionsOnSave\": {\n \"quickfix.biome\": \"explicit\",\n \"source.organizeImports.biome\": \"explicit\"\n },\n \"[javascript]\": {\n \"editor.defaultFormatter\": \"biomejs.biome\"\n },\n \"[typescript]\": {\n \"editor.defaultFormatter\": \"biomejs.biome\"\n },\n \"[json]\": {\n \"editor.defaultFormatter\": \"biomejs.biome\"\n }\n}\n`;\n\n/**\n * Biomeのセットアップを実行する(--setupモードのみ)\n *\n * AC-006-1: biome.json が生成される\n * AC-006-2: package.jsonにlint/formatスクリプトが追加される\n * AC-006-3: VSCode設定が追加される\n */\nexport function setupBiome(options: ToolSetupOptions): void {\n const { targetDir, conflictStrategy } = options;\n\n const biomeConfigPath = join(targetDir, \"biome.json\");\n writeWithStrategy(biomeConfigPath, BIOME_CONFIG, conflictStrategy);\n\n addDependencies(\n targetDir,\n {\n \"@biomejs/biome\": \"^1.9.4\",\n },\n true\n );\n\n addScripts(targetDir, {\n lint: \"biome lint .\",\n \"lint:fix\": \"biome lint --write .\",\n format: \"biome format .\",\n \"format:fix\": \"biome format --write .\",\n });\n\n const vscodeDir = join(targetDir, \".vscode\");\n ensureDir(vscodeDir);\n\n const vscodeSettingsPath = join(vscodeDir, \"settings.json\");\n writeWithStrategy(vscodeSettingsPath, VSCODE_SETTINGS, conflictStrategy);\n}\n","import { join } from \"node:path\";\nimport { writeFileSync } from \"node:fs\";\nimport type { ToolSetupOptions } from \"../../types/index.js\";\nimport { ensureDir } from \"../../utils/fs.js\";\nimport { addDependencies, addScripts, addLintStaged } from \"../../utils/package-json.js\";\n\nconst PRE_COMMIT_HOOK = `#!/usr/bin/env sh\n. \"$(dirname -- \"$0\")/_/husky.sh\"\n\npnpm lint-staged\n`;\n\n/**\n * Husky + lint-stagedのセットアップを実行する(--setupモードのみ)\n *\n * AC-007-1: .husky/ ディレクトリが生成される\n * AC-007-2: pre-commitフックが設定される\n * AC-007-3: lint-staged設定が追加される\n */\nexport function setupHusky(options: ToolSetupOptions): void {\n const { targetDir } = options;\n\n addDependencies(\n targetDir,\n {\n husky: \"^9.1.7\",\n \"lint-staged\": \"^15.2.11\",\n },\n true\n );\n\n addScripts(targetDir, {\n prepare: \"husky\",\n });\n\n addLintStaged(targetDir, {\n \"*.{js,jsx,ts,tsx}\": [\"biome format --write\", \"biome lint --write\"],\n \"*.{json,md,yml,yaml}\": [\"biome format --write\"],\n });\n\n const huskyDir = join(targetDir, \".husky\");\n ensureDir(huskyDir);\n\n const preCommitPath = join(huskyDir, \"pre-commit\");\n writeFileSync(preCommitPath, PRE_COMMIT_HOOK, { mode: 0o755 });\n}\n"],"mappings":"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","names":["readFileSync","fileURLToPath","dirname","join","existsSync","ora","dirname","join","readFileSync","writeFileSync","existsSync","__filename","__dirname","dirname","join","error","chalk","inquirer","inquirer","error","chalk","existsSync","error","ora","existsSync","join","ora","inquirer","join","inquirer","join","inquirer","error","join","readFileSync","writeFileSync","join","packageJsonPath","join","readFileSync","writeFileSync","join","join","join","join","join","join","writeFileSync","join","writeFileSync","packageJsonPath","join","existsSync","ora","error","__filename","fileURLToPath","__dirname","dirname","join","readFileSync"]}
1
+ {"version":3,"sources":["../src/cli.ts","../src/commands/create.ts","../src/prompts/project.ts","../src/generators/template.ts","../src/utils/fs.ts","../src/utils/logger.ts","../src/generators/post-setup.ts","../src/commands/setup.ts","../src/prompts/setup.ts","../src/generators/tools/direnv.ts","../src/generators/tools/dotenvx.ts","../src/utils/package-json.ts","../src/generators/tools/volta.ts","../src/generators/tools/biome.ts","../src/generators/tools/husky.ts"],"sourcesContent":["import { Command } from \"commander\";\nimport { readFileSync } from \"node:fs\";\nimport { fileURLToPath } from \"node:url\";\nimport { dirname, join } from \"node:path\";\nimport { createCommand } from \"./commands/create.js\";\nimport { setupCommand } from \"./commands/setup.js\";\n\n// package.jsonからバージョン情報を読み込み\nconst __filename = fileURLToPath(import.meta.url);\nconst __dirname = dirname(__filename);\nconst packageJsonPath = join(__dirname, \"../package.json\");\nconst packageJson = JSON.parse(readFileSync(packageJsonPath, \"utf-8\"));\n\nconst program = new Command();\n\nprogram\n .name(\"create-einja-app\")\n .description(\"CLI tool to create new projects with Einja Management Template\")\n .version(packageJson.version);\n\n// createコマンド\nprogram\n .argument(\"[project-name]\", \"Project name\")\n .option(\"--skip-git\", \"Skip git initialization\")\n .option(\"--skip-install\", \"Skip package installation\")\n .option(\"-y, --yes\", \"Skip interactive prompts\")\n .action(\n async (\n projectName: string | undefined,\n options: {\n skipGit?: boolean;\n skipInstall?: boolean;\n yes?: boolean;\n }\n ) => {\n await createCommand(projectName, options);\n }\n );\n\n// setupコマンド\nprogram\n .command(\"setup\")\n .description(\"Setup tools for existing project\")\n .action(async () => {\n await setupCommand();\n });\n\nprogram.parse();\n","import { existsSync } from \"node:fs\";\nimport { resolve } from \"node:path\";\nimport ora from \"ora\";\nimport { promptProjectConfig, type ProjectConfig } from \"../prompts/project.js\";\nimport { generateTemplate } from \"../generators/template.js\";\nimport { execPostSetup } from \"../generators/post-setup.js\";\nimport * as logger from \"../utils/logger.js\";\n\n/**\n * CreateOptions型\n * createコマンドのオプション\n */\ninterface CreateOptions {\n skipGit?: boolean;\n skipInstall?: boolean;\n yes?: boolean;\n}\n\n/**\n * プロジェクト名のバリデーション\n * @param projectName - プロジェクト名\n * @returns エラーメッセージ(問題なければundefined)\n */\nfunction validateProjectName(projectName: string): string | undefined {\n const regex = /^[a-zA-Z][a-zA-Z0-9_-]{0,49}$/;\n if (!regex.test(projectName)) {\n return \"プロジェクト名は英字で始まり、英数字・ハイフン・アンダースコアのみ使用できます(1〜50文字)\";\n }\n return undefined;\n}\n\n/**\n * プロジェクトディレクトリの存在確認\n * @param targetPath - ターゲットパス\n * @returns 存在する場合true\n */\nfunction checkProjectExists(targetPath: string): boolean {\n return existsSync(targetPath);\n}\n\n\n/**\n * createコマンドの実装\n * @param projectName - プロジェクト名(オプション)\n * @param options - コマンドオプション\n */\nexport async function createCommand(\n projectName: string | undefined,\n options: CreateOptions\n): Promise<void> {\n try {\n // プロンプトで設定収集\n let config: ProjectConfig;\n\n if (options.yes && projectName) {\n // --yes オプション: デフォルト値を使用\n const error = validateProjectName(projectName);\n if (error) {\n logger.error(error);\n process.exit(1);\n }\n\n config = {\n projectName,\n packageScope: \"@repo\",\n template: \"default\",\n authMethod: \"default\",\n tools: {\n direnv: true,\n dotenvx: true,\n volta: true,\n biome: true,\n husky: true,\n },\n setupEinjaCli: true,\n worktreeConfig: undefined,\n };\n\n logger.info(`プロジェクト名: ${config.projectName}`);\n logger.info(`テンプレート: ${config.template}`);\n logger.info(`認証方式: ${config.authMethod}`);\n } else {\n // 対話式プロンプト\n config = await promptProjectConfig(projectName);\n }\n\n // ターゲットパスの解決\n const targetPath = resolve(process.cwd(), config.projectName);\n\n // プロジェクトディレクトリの存在確認\n if (checkProjectExists(targetPath)) {\n logger.error(`ディレクトリ '${config.projectName}' は既に存在します`);\n logger.info(\"別の名前を指定するか、既存ディレクトリを削除してください\");\n process.exit(1);\n }\n\n // テンプレート展開\n const spinner = ora(\"プロジェクトを作成中...\").start();\n\n try {\n await generateTemplate(config, targetPath);\n spinner.succeed(\"プロジェクトを作成しました\");\n } catch (error) {\n spinner.fail(\"プロジェクトの作成に失敗しました\");\n throw error;\n }\n\n // 生成後セットアップ実行\n await execPostSetup(config, targetPath, {\n skipGit: options.skipGit,\n skipInstall: options.skipInstall,\n });\n } catch (error) {\n logger.error(\"エラーが発生しました:\");\n if (error instanceof Error) {\n logger.error(error.message);\n } else {\n logger.error(String(error));\n }\n process.exit(1);\n }\n}\n","import inquirer from \"inquirer\";\nimport type { ProjectConfig, WorktreeConfig, App } from \"../types/index.js\";\n\nexport type { ProjectConfig, WorktreeConfig, App };\n\n/**\n * プロジェクト作成用プロンプトを実行\n * @param defaultProjectName - デフォルトのプロジェクト名\n * @returns ProjectConfig - プロジェクト設定\n */\nexport async function promptProjectConfig(\n defaultProjectName?: string\n): Promise<ProjectConfig> {\n const answers = await inquirer.prompt([\n {\n type: \"input\",\n name: \"projectName\",\n message: \"プロジェクト名:\",\n default: defaultProjectName || \"my-project\",\n validate: (input: string): boolean | string => {\n // 英数字・ハイフン・アンダースコアのみ許可、先頭は英字、1〜50文字\n const regex = /^[a-zA-Z][a-zA-Z0-9_-]{0,49}$/;\n if (!regex.test(input)) {\n return \"プロジェクト名は英字で始まり、英数字・ハイフン・アンダースコアのみ使用できます(1〜50文字)\";\n }\n return true;\n },\n },\n {\n type: \"input\",\n name: \"packageScope\",\n message: \"パッケージスコープ:\",\n default: \"@repo\",\n validate: (input: string): boolean | string => {\n // @で始まり、英数字・ハイフン・アンダースコアのみ許可\n const regex = /^@[a-zA-Z][a-zA-Z0-9_-]{0,49}$/;\n if (!regex.test(input)) {\n return \"パッケージスコープは@で始まり、英数字・ハイフン・アンダースコアのみ使用できます\";\n }\n return true;\n },\n },\n {\n type: \"list\",\n name: \"authMethod\",\n message: \"認証機能:\",\n choices: [\n { name: \"NextAuth.js を使用\", value: \"default\" },\n { name: \"なし(認証ファイルを除外)\", value: \"none\" },\n ],\n default: \"default\",\n },\n {\n type: \"confirm\",\n name: \"setupEinjaCli\",\n message: \"@einja/cli を自動セットアップしますか?\",\n default: true,\n },\n {\n type: \"confirm\",\n name: \"customizeWorktree\",\n message: \"Worktree設定をカスタマイズしますか?\",\n default: false,\n },\n ]);\n\n // ツールは全て有効(固定)\n const tools = {\n direnv: true,\n dotenvx: true,\n volta: true,\n biome: true,\n husky: true,\n };\n\n let worktreeConfig: WorktreeConfig | undefined;\n\n // Worktree設定カスタマイズ\n if (answers.customizeWorktree) {\n const worktreeAnswers = await inquirer.prompt([\n {\n type: \"input\",\n name: \"postgresPort\",\n message: \"PostgreSQLポート番号:\",\n default: \"25432\",\n validate: (input: string): boolean | string => {\n const port = Number.parseInt(input, 10);\n if (Number.isNaN(port) || port < 1024 || port > 65535) {\n return \"ポート番号は1024〜65535の範囲で指定してください\";\n }\n return true;\n },\n },\n {\n type: \"input\",\n name: \"containerName\",\n message: \"Dockerコンテナ名:\",\n default: `${answers.projectName}-postgres`,\n },\n {\n type: \"input\",\n name: \"appId\",\n message: \"アプリケーションID:\",\n default: \"web\",\n },\n {\n type: \"input\",\n name: \"portRangeStart\",\n message: \"アプリポート範囲開始:\",\n default: \"3000\",\n validate: (input: string): boolean | string => {\n const port = Number.parseInt(input, 10);\n if (Number.isNaN(port) || port < 1024 || port > 65535) {\n return \"ポート番号は1024〜65535の範囲で指定してください\";\n }\n return true;\n },\n },\n {\n type: \"input\",\n name: \"rangeSize\",\n message: \"ポート範囲サイズ:\",\n default: \"1000\",\n validate: (input: string): boolean | string => {\n const size = Number.parseInt(input, 10);\n if (Number.isNaN(size) || size < 1 || size > 10000) {\n return \"範囲サイズは1〜10000の範囲で指定してください\";\n }\n return true;\n },\n },\n ]);\n\n worktreeConfig = {\n postgres: {\n port: Number.parseInt(worktreeAnswers.postgresPort, 10),\n containerName: worktreeAnswers.containerName,\n },\n apps: [\n {\n id: worktreeAnswers.appId,\n portRangeStart: Number.parseInt(worktreeAnswers.portRangeStart, 10),\n rangeSize: Number.parseInt(worktreeAnswers.rangeSize, 10),\n },\n ],\n };\n }\n\n return {\n projectName: answers.projectName,\n packageScope: answers.packageScope,\n template: \"default\" as const,\n authMethod: answers.authMethod,\n tools,\n setupEinjaCli: answers.setupEinjaCli,\n worktreeConfig,\n };\n}\n","import fsExtra from \"fs-extra\";\nconst { copySync, readFileSync, writeFileSync, existsSync, removeSync } = fsExtra;\nimport { glob } from \"glob\";\nimport { dirname, join, relative } from \"node:path\";\nimport { fileURLToPath } from \"node:url\";\nimport type { ProjectConfig } from \"../prompts/project.js\";\nimport { ensureDir } from \"../utils/fs.js\";\nimport * as logger from \"../utils/logger.js\";\n\n/**\n * TemplateVariables型\n * テンプレート変数(プレースホルダー置換用)\n */\nexport interface TemplateVariables {\n projectName: string;\n packageName: string;\n description: string;\n}\n\n/**\n * テンプレートディレクトリのパスを取得\n * @param templateName - テンプレート名\n * @returns テンプレートディレクトリパス\n */\nfunction getTemplatePath(templateName: string): string {\n const __filename = fileURLToPath(import.meta.url);\n const __dirname = dirname(__filename);\n\n // バンドル後(dist/cli.js)とソース実行(src/generators/template.ts)の両方に対応\n // dist/cli.js -> ../templates/ (1階層上)\n // src/generators/template.ts -> ../../templates/ (2階層上)\n const distPath = join(__dirname, \"../templates\", templateName);\n const srcPath = join(__dirname, \"../../templates\", templateName);\n\n if (existsSync(distPath)) {\n return distPath;\n }\n if (existsSync(srcPath)) {\n return srcPath;\n }\n\n // どちらも存在しない場合はdistPathを返す(エラーメッセージ用)\n return distPath;\n}\n\n/**\n * 認証方式に応じた除外パターンを取得\n * @param authMethod - 認証方式\n * @returns 除外パターン配列\n */\nfunction getAuthExcludePatterns(authMethod: string): string[] {\n if (authMethod === \"none\") {\n return [\n \"**/api/auth/**\",\n \"**/packages/auth/**\",\n \"**/signin/**\",\n \"**/signup/**\",\n ];\n }\n return [];\n}\n\n/**\n * ファイル内容のプレースホルダー変数を置換\n * @param content - ファイル内容\n * @param variables - 置換する変数\n * @returns 置換後の内容\n */\nfunction replacePlaceholders(\n content: string,\n variables: TemplateVariables\n): string {\n let result = content;\n\n // {{projectName}} の置換\n result = result.replaceAll(\"{{projectName}}\", variables.projectName);\n\n // {{packageName}}/ の置換(長いパターンを先に置換)\n result = result.replaceAll(\"{{packageName}}/\", `${variables.packageName}/`);\n\n // {{packageName}} の置換\n result = result.replaceAll(\"{{packageName}}\", variables.packageName);\n\n // {{description}} の置換\n result = result.replaceAll(\"{{description}}\", variables.description);\n\n // @repo/ の置換(パッケージスコープ)\n result = result.replaceAll(\"@repo/\", `${variables.packageName}/`);\n\n return result;\n}\n\n/**\n * ファイルの変数置換処理\n * @param filePath - ファイルパス\n * @param variables - 置換する変数\n */\nfunction processFileVariables(\n filePath: string,\n variables: TemplateVariables\n): void {\n // バイナリファイルは処理しない\n const binaryExtensions = [\".png\", \".jpg\", \".jpeg\", \".gif\", \".ico\", \".woff\", \".woff2\", \".ttf\", \".eot\"];\n if (binaryExtensions.some((ext) => filePath.endsWith(ext))) {\n return;\n }\n\n try {\n const content = readFileSync(filePath, \"utf-8\");\n const replaced = replacePlaceholders(content, variables);\n\n if (content !== replaced) {\n writeFileSync(filePath, replaced, \"utf-8\");\n }\n } catch (error) {\n // 読み込みに失敗した場合はスキップ(バイナリファイル等)\n logger.warn(`変数置換をスキップ: ${filePath}`);\n }\n}\n\n/**\n * .templateファイルのリネーム処理\n * @param targetPath - ターゲットディレクトリパス\n */\nfunction renameTemplateFiles(targetPath: string): void {\n const templateFiles = glob.sync(\"**/*.template\", {\n cwd: targetPath,\n absolute: true,\n dot: true,\n });\n\n for (const file of templateFiles) {\n const newPath = file.replace(/\\.template$/, \"\");\n copySync(file, newPath);\n removeSync(file);\n }\n}\n\n/**\n * 認証方式に応じたファイル除外処理\n * @param targetPath - ターゲットディレクトリパス\n * @param authMethod - 認証方式\n */\nfunction excludeAuthFiles(targetPath: string, authMethod: string): void {\n const excludePatterns = getAuthExcludePatterns(authMethod);\n\n if (excludePatterns.length === 0) {\n return;\n }\n\n logger.info(\"認証方式に応じたファイルを除外中...\");\n\n for (const pattern of excludePatterns) {\n const files = glob.sync(pattern, {\n cwd: targetPath,\n absolute: true,\n dot: true,\n });\n\n for (const file of files) {\n removeSync(file);\n }\n }\n}\n\n/**\n * テンプレートを展開\n * @param config - プロジェクト設定\n * @param targetPath - ターゲットディレクトリパス\n */\nexport async function generateTemplate(\n config: ProjectConfig,\n targetPath: string\n): Promise<void> {\n const templatePath = getTemplatePath(config.template);\n\n // テンプレートディレクトリの存在確認\n if (!existsSync(templatePath)) {\n throw new Error(`テンプレートが見つかりません: ${config.template}`);\n }\n\n logger.info(\"テンプレートをコピー中...\");\n\n // ターゲットディレクトリの作成\n await ensureDir(targetPath);\n\n // テンプレートファイルをコピー\n copySync(templatePath, targetPath, {\n filter: (src: string): boolean => {\n const relativePath = relative(templatePath, src);\n\n // 除外パターン(ディレクトリ名やファイル名として完全一致するもの)\n const excludePatterns = [\n \"node_modules\",\n \".git\",\n \".next\",\n \".turbo\",\n \"out\",\n \"dist\",\n \"logs\",\n \".env\",\n \".env.local\",\n \".DS_Store\",\n \"Thumbs.db\",\n \"coverage\",\n ];\n\n // ファイル拡張子パターン(*.log など)\n const excludeExtensions = [\".log\"];\n\n // パスセグメントに分割(/ または \\ で分割)\n const pathSegments = relativePath.split(/[/\\\\]/);\n\n // パスセグメント単位で完全一致チェック\n // これにより \"out\" は \"out/\" ディレクトリにマッチするが\n // \"logout-button.tsx\" にはマッチしない\n const matchesExcludePattern = excludePatterns.some((pattern) =>\n pathSegments.includes(pattern)\n );\n\n // 拡張子チェック\n const matchesExtension = excludeExtensions.some((ext) =>\n relativePath.endsWith(ext)\n );\n\n return !matchesExcludePattern && !matchesExtension;\n },\n });\n\n // 認証方式に応じたファイル除外\n excludeAuthFiles(targetPath, config.authMethod);\n\n // .templateファイルのリネーム\n renameTemplateFiles(targetPath);\n\n // 変数置換\n logger.info(\"プレースホルダー変数を置換中...\");\n\n const variables: TemplateVariables = {\n projectName: config.projectName,\n packageName: config.packageScope,\n description: `${config.projectName} - Einja Management Template`,\n };\n\n const allFiles = glob.sync(\"**/*\", {\n cwd: targetPath,\n absolute: true,\n nodir: true,\n dot: true,\n });\n\n for (const file of allFiles) {\n processFileVariables(file, variables);\n }\n\n logger.success(\"テンプレート展開完了\");\n}\n","import { existsSync, readFileSync, writeFileSync, appendFileSync, mkdirSync } from \"node:fs\";\nimport { join, dirname } from \"node:path\";\nimport type { ConflictStrategy } from \"../types/index.js\";\n\n/**\n * 競合戦略に基づいてファイルを書き込む\n */\nexport function writeWithStrategy(\n filePath: string,\n content: string,\n strategy: ConflictStrategy\n): boolean {\n const exists = existsSync(filePath);\n\n if (!exists) {\n ensureDir(dirname(filePath));\n writeFileSync(filePath, content, \"utf-8\");\n return true;\n }\n\n switch (strategy) {\n case \"overwrite\": {\n writeFileSync(filePath, content, \"utf-8\");\n return true;\n }\n\n case \"merge\": {\n const existingContent = readFileSync(filePath, \"utf-8\");\n const mergedContent = mergeContent(existingContent, content);\n writeFileSync(filePath, mergedContent, \"utf-8\");\n return true;\n }\n\n case \"skip\": {\n return false;\n }\n\n default: {\n const _exhaustiveCheck: never = strategy;\n throw new Error(`Unknown strategy: ${_exhaustiveCheck}`);\n }\n }\n}\n\n/**\n * 既存コンテンツと新規コンテンツをマージする\n */\nfunction mergeContent(existing: string, newContent: string): string {\n if (existing.includes(newContent)) {\n return existing;\n }\n return `${existing}\\n${newContent}`;\n}\n\n/**\n * ディレクトリが存在しない場合は作成する\n */\nexport function ensureDir(dirPath: string): void {\n if (!existsSync(dirPath)) {\n mkdirSync(dirPath, { recursive: true });\n }\n}\n\n/**\n * .gitignoreに行を追加する\n */\nexport function appendToGitignore(targetDir: string, line: string): void {\n const gitignorePath = join(targetDir, \".gitignore\");\n\n if (!existsSync(gitignorePath)) {\n writeFileSync(gitignorePath, `${line}\\n`, \"utf-8\");\n return;\n }\n\n const content = readFileSync(gitignorePath, \"utf-8\");\n if (content.includes(line)) {\n return;\n }\n\n appendFileSync(gitignorePath, `\\n${line}\\n`, \"utf-8\");\n}\n\n/**\n * ファイルが存在するか確認する\n */\nexport function fileExists(filePath: string): boolean {\n return existsSync(filePath);\n}\n","import chalk from \"chalk\";\n\n/**\n * 情報メッセージを出力\n * @param message - メッセージ\n */\nexport function info(message: string): void {\n console.log(chalk.blue(\"ℹ\"), message);\n}\n\n/**\n * 成功メッセージを出力(緑色)\n * @param message - メッセージ\n */\nexport function success(message: string): void {\n console.log(chalk.green(\"✔\"), message);\n}\n\n/**\n * 警告メッセージを出力(黄色)\n * @param message - メッセージ\n */\nexport function warn(message: string): void {\n console.log(chalk.yellow(\"⚠\"), message);\n}\n\n/**\n * エラーメッセージを出力(赤色)\n * @param message - メッセージ\n */\nexport function error(message: string): void {\n console.error(chalk.red(\"✖\"), message);\n}\n","import { execa, execaSync } from \"execa\";\nimport chalk from \"chalk\";\nimport inquirer from \"inquirer\";\nimport ora from \"ora\";\nimport type { ProjectConfig } from \"../types/index.js\";\nimport * as logger from \"../utils/logger.js\";\n\n/**\n * PostSetupOptions型\n * 生成後セットアップのオプション\n */\nexport interface PostSetupOptions {\n skipGit?: boolean;\n skipInstall?: boolean;\n}\n\n/**\n * direnvコマンドが利用可能かチェック\n * @returns direnvコマンドが利用可能な場合true\n */\nfunction isDirenvAvailable(): boolean {\n try {\n execaSync(\"which\", [\"direnv\"]);\n return true;\n } catch {\n return false;\n }\n}\n\n/**\n * direnv allowの確認プロンプトを表示し、実行する\n * @param targetPath - プロジェクトディレクトリ\n */\nasync function promptAndExecuteDirenvAllow(targetPath: string): Promise<void> {\n try {\n const { shouldAllow } = await inquirer.prompt([\n {\n type: \"confirm\",\n name: \"shouldAllow\",\n message: \"direnv allow を実行しますか?(環境変数を有効化します)\",\n default: true,\n },\n ]);\n\n if (shouldAllow) {\n try {\n await execa(\"direnv\", [\"allow\"], { cwd: targetPath });\n logger.success(\"direnv allow を実行しました\");\n } catch (error) {\n logger.warn(\"direnv allow の実行に失敗しました\");\n logger.info(\"後で手動で 'direnv allow' を実行してください\");\n }\n } else {\n logger.info(\"direnv allow をスキップしました\");\n logger.info(\"後で手動で 'direnv allow' を実行してください\");\n }\n } catch (error) {\n logger.info(\"direnv allow をスキップしました\");\n }\n}\n\n/**\n * 完了メッセージを表示\n * @param config - プロジェクト設定\n */\nfunction printCompletionMessage(config: ProjectConfig): void {\n console.log();\n logger.success(\"プロジェクトの作成が完了しました!\");\n console.log();\n console.log(chalk.bold(\"次のステップ:\"));\n console.log();\n console.log(chalk.cyan(` cd ${config.projectName}`));\n console.log(chalk.cyan(\" docker-compose up -d postgres\"));\n console.log(chalk.cyan(\" pnpm dev\"));\n console.log();\n console.log(chalk.gray(\"開発サーバー: http://localhost:3000\"));\n console.log();\n console.log(chalk.gray(\"詳細は README.md をご確認ください。\"));\n console.log();\n}\n\n/**\n * 生成後セットアップを実行\n * @param config - プロジェクト設定\n * @param targetPath - プロジェクトディレクトリ\n * @param options - セットアップオプション\n */\nexport async function execPostSetup(\n config: ProjectConfig,\n targetPath: string,\n options: PostSetupOptions\n): Promise<void> {\n const { skipGit, skipInstall } = options;\n\n // Git初期化\n if (!skipGit) {\n const gitSpinner = ora(\"Gitリポジトリを初期化中...\").start();\n try {\n await execa(\"git\", [\"init\"], { cwd: targetPath });\n await execa(\"git\", [\"add\", \".\"], { cwd: targetPath });\n await execa(\"git\", [\"commit\", \"-m\", \"Initial commit\"], { cwd: targetPath });\n gitSpinner.succeed(\"Gitリポジトリを初期化しました\");\n } catch (error) {\n gitSpinner.fail(\"Gitリポジトリの初期化に失敗しました\");\n logger.warn(\"後で手動で 'git init' を実行してください\");\n }\n }\n\n // 依存関係インストール\n if (!skipInstall) {\n const installSpinner = ora(\"依存関係をインストール中...\").start();\n try {\n await execa(\"pnpm\", [\"install\"], { cwd: targetPath });\n installSpinner.succeed(\"依存関係をインストールしました\");\n\n // Prismaクライアント生成\n const prismaSpinner = ora(\"Prismaクライアントを生成中...\").start();\n try {\n await execa(\"pnpm\", [\"db:generate\"], { cwd: targetPath });\n prismaSpinner.succeed(\"Prismaクライアントを生成しました\");\n } catch (error) {\n prismaSpinner.fail(\"Prismaクライアントの生成に失敗しました\");\n logger.warn(\"後で手動で 'pnpm db:generate' を実行してください\");\n }\n } catch (error) {\n installSpinner.fail(\"依存関係のインストールに失敗しました\");\n logger.warn(\"後で手動で 'pnpm install' を実行してください\");\n }\n }\n\n // direnv allow(direnvが有効で、コマンドが利用可能な場合)\n if (config.tools.direnv && isDirenvAvailable()) {\n await promptAndExecuteDirenvAllow(targetPath);\n }\n\n // @einja/cli init\n if (config.setupEinjaCli) {\n const einjaSpinner = ora(\"@einja/cli を初期化中...\").start();\n try {\n await execa(\"npx\", [\"@einja/cli\", \"init\"], { cwd: targetPath });\n einjaSpinner.succeed(\"@einja/cli を初期化しました\");\n } catch (error) {\n einjaSpinner.fail(\"@einja/cli の初期化に失敗しました\");\n logger.warn(\"後で手動で 'npx @einja/cli init' を実行してください\");\n }\n }\n\n // 完了メッセージ表示\n printCompletionMessage(config);\n}\n","import { existsSync } from \"node:fs\";\nimport { join } from \"node:path\";\nimport ora from \"ora\";\nimport { promptSetupConfig } from \"../prompts/setup.js\";\nimport {\n setupDirenv,\n setupDotenvx,\n setupVolta,\n setupBiome,\n setupHusky,\n promptDirenvAllow,\n} from \"../generators/tools/index.js\";\nimport type { ToolSetupOptions } from \"../types/index.js\";\nimport * as logger from \"../utils/logger.js\";\n\n/**\n * setupコマンド - 既存プロジェクトへのツール追加\n *\n * US-002: 既存プロジェクトへの環境ツール追加\n * AC-002-1: `npx create-einja-app --setup` で対話式プロンプトが表示される\n * AC-002-2: 既存の設定ファイルがある場合、マージ・上書き・スキップを選択できる\n * AC-002-3: 選択したツールのみがセットアップされる\n * AC-002-4: 既存ファイルを破壊せずにツールが追加される(マージモード時)\n */\nexport async function setupCommand(): Promise<void> {\n const targetDir = process.cwd();\n\n // 1. プロジェクトディレクトリ確認(package.json存在確認)\n const packageJsonPath = join(targetDir, \"package.json\");\n if (!existsSync(packageJsonPath)) {\n logger.error(\"エラー: package.jsonが見つかりません\");\n logger.info(\"このコマンドは既存のプロジェクトディレクトリで実行してください\");\n process.exit(1);\n }\n\n logger.info(\"既存プロジェクトへのツール追加を開始します\");\n logger.info(\"\");\n\n // 2. プロンプトで設定収集\n const config = await promptSetupConfig();\n\n logger.info(\"\");\n logger.info(\"セットアップを開始します...\");\n logger.info(\"\");\n\n const options: ToolSetupOptions = {\n targetDir,\n conflictStrategy: config.conflictStrategy,\n };\n\n // 3. 選択されたツールのセットアップ\n let setupCount = 0;\n\n if (config.tools.direnv) {\n const spin = ora(\"direnv をセットアップしています...\").start();\n try {\n setupDirenv(options);\n spin.succeed(\"direnv セットアップ完了\");\n setupCount++;\n } catch (error) {\n spin.fail(\"direnv セットアップ失敗\");\n logger.error(\n error instanceof Error ? error.message : \"予期しないエラーが発生しました\"\n );\n }\n }\n\n if (config.tools.dotenvx) {\n const spin = ora(\"dotenvx をセットアップしています...\").start();\n try {\n setupDotenvx(options);\n spin.succeed(\"dotenvx セットアップ完了\");\n setupCount++;\n } catch (error) {\n spin.fail(\"dotenvx セットアップ失敗\");\n logger.error(\n error instanceof Error ? error.message : \"予期しないエラーが発生しました\"\n );\n }\n }\n\n if (config.tools.volta) {\n const spin = ora(\"Volta をセットアップしています...\").start();\n try {\n setupVolta(options);\n spin.succeed(\"Volta セットアップ完了\");\n setupCount++;\n } catch (error) {\n spin.fail(\"Volta セットアップ失敗\");\n logger.error(\n error instanceof Error ? error.message : \"予期しないエラーが発生しました\"\n );\n }\n }\n\n if (config.tools.biome) {\n const spin = ora(\"Biome をセットアップしています...\").start();\n try {\n setupBiome(options);\n spin.succeed(\"Biome セットアップ完了\");\n setupCount++;\n } catch (error) {\n spin.fail(\"Biome セットアップ失敗\");\n logger.error(\n error instanceof Error ? error.message : \"予期しないエラーが発生しました\"\n );\n }\n }\n\n if (config.tools.husky) {\n const spin = ora(\"Husky をセットアップしています...\").start();\n try {\n setupHusky(options);\n spin.succeed(\"Husky セットアップ完了\");\n setupCount++;\n } catch (error) {\n spin.fail(\"Husky セットアップ失敗\");\n logger.error(\n error instanceof Error ? error.message : \"予期しないエラーが発生しました\"\n );\n }\n }\n\n logger.info(\"\");\n\n // 4. direnv allowの確認プロンプト(direnvがセットアップされた場合のみ)\n if (config.tools.direnv) {\n await promptDirenvAllow(targetDir);\n logger.info(\"\");\n }\n\n // 5. 完了メッセージ\n logger.success(`✅ セットアップが完了しました!(${setupCount}個のツール)`);\n logger.info(\"\");\n logger.info(\"次のステップ:\");\n\n if (config.tools.direnv) {\n logger.info(\" 1. .envrc を編集して環境変数を設定\");\n logger.info(\" 2. direnv allow を実行(まだの場合)\");\n }\n\n if (config.tools.dotenvx) {\n logger.info(\" - .env.example をコピーして .env を作成\");\n logger.info(\" - 必要に応じて pnpm env:encrypt で暗号化\");\n }\n\n if (config.tools.biome) {\n logger.info(\" - pnpm lint でコードをチェック\");\n logger.info(\" - pnpm format:fix でフォーマット\");\n }\n\n if (config.tools.husky) {\n logger.info(\" - pnpm install でHuskyフックをインストール\");\n }\n\n logger.info(\"\");\n logger.success(\"開発を開始できます!\");\n}\n","import inquirer from \"inquirer\";\n\n/**\n * SetupConfig型\n * 既存プロジェクトへのツール追加設定\n */\nexport interface SetupConfig {\n tools: {\n direnv: boolean;\n dotenvx: boolean;\n volta: boolean;\n biome: boolean;\n husky: boolean;\n };\n conflictStrategy: \"merge\" | \"overwrite\" | \"skip\";\n}\n\n/**\n * セットアップ用プロンプトを実行\n * @returns SetupConfig - セットアップ設定\n */\nexport async function promptSetupConfig(): Promise<SetupConfig> {\n const answers = await inquirer.prompt([\n {\n type: \"checkbox\",\n name: \"tools\",\n message: \"セットアップするツールを選択(複数選択可):\",\n choices: [\n {\n name: \"direnv(ディレクトリごとの環境変数管理)\",\n value: \"direnv\",\n checked: true,\n },\n {\n name: \"dotenvx(.env暗号化)\",\n value: \"dotenvx\",\n checked: true,\n },\n {\n name: \"Volta(Node.jsバージョン管理)\",\n value: \"volta\",\n checked: true,\n },\n {\n name: \"Biome(Linter / Formatter)\",\n value: \"biome\",\n checked: false,\n },\n {\n name: \"Husky + lint-staged(Git hooks)\",\n value: \"husky\",\n checked: false,\n },\n ],\n },\n {\n type: \"list\",\n name: \"conflictStrategy\",\n message: \"既存ファイルがある場合の動作:\",\n choices: [\n {\n name: \"マージ(既存設定を保持しつつ追加)\",\n value: \"merge\",\n },\n {\n name: \"上書き\",\n value: \"overwrite\",\n },\n {\n name: \"スキップ\",\n value: \"skip\",\n },\n ],\n default: \"merge\",\n },\n ]);\n\n // ツール選択を boolean フラグに変換\n const toolsArray = answers.tools as string[];\n const tools = {\n direnv: toolsArray.includes(\"direnv\"),\n dotenvx: toolsArray.includes(\"dotenvx\"),\n volta: toolsArray.includes(\"volta\"),\n biome: toolsArray.includes(\"biome\"),\n husky: toolsArray.includes(\"husky\"),\n };\n\n return {\n tools,\n conflictStrategy: answers.conflictStrategy,\n };\n}\n","import { join } from \"node:path\";\nimport { execSync } from \"node:child_process\";\nimport inquirer from \"inquirer\";\nimport type { ToolSetupOptions } from \"../../types/index.js\";\nimport { writeWithStrategy, appendToGitignore } from \"../../utils/fs.js\";\nimport * as logger from \"../../utils/logger.js\";\n\nconst ENVRC_CONTENT = `# direnv configuration\n# Load .env if it exists\ndotenv_if_exists\n\n# Allow local overrides\ndotenv_if_exists .env.local\n`;\n\nconst ENVRC_EXAMPLE_CONTENT = `# Example direnv configuration\n# Copy this file to .envrc and run 'direnv allow'\n\n# Load environment variables from .env\ndotenv_if_exists\n\n# Load local overrides\ndotenv_if_exists .env.local\n`;\n\n/**\n * direnvのセットアップを実行する\n *\n * AC-003-1: .envrc ファイルが生成される\n * AC-003-2: .envrc.example ファイルが生成される\n * AC-003-3: .gitignore に .envrc が追加される\n */\nexport function setupDirenv(options: ToolSetupOptions): void {\n const { targetDir, conflictStrategy } = options;\n\n const envrcPath = join(targetDir, \".envrc\");\n const envrcExamplePath = join(targetDir, \".envrc.example\");\n\n writeWithStrategy(envrcPath, ENVRC_CONTENT, conflictStrategy);\n\n writeWithStrategy(envrcExamplePath, ENVRC_EXAMPLE_CONTENT, conflictStrategy);\n\n appendToGitignore(targetDir, \".envrc\");\n}\n\n/**\n * direnv allowの確認プロンプトを表示し、実行する\n *\n * AC-003-4: 確認後 `direnv allow` が実行される\n *\n * @param targetDir - ターゲットディレクトリ\n */\nexport async function promptDirenvAllow(targetDir: string): Promise<void> {\n try {\n const { shouldAllow } = await inquirer.prompt([\n {\n type: \"confirm\",\n name: \"shouldAllow\",\n message: \"direnv allow を実行しますか?(環境変数を有効化します)\",\n default: true,\n },\n ]);\n\n if (shouldAllow) {\n try {\n execSync(\"direnv allow\", { cwd: targetDir, stdio: \"inherit\" });\n logger.success(\"direnv allow を実行しました\");\n } catch (error) {\n logger.warn(\"direnv allow の実行に失敗しました\");\n logger.info(\"後で手動で 'direnv allow' を実行してください\");\n }\n } else {\n logger.info(\"direnv allow をスキップしました\");\n logger.info(\"後で手動で 'direnv allow' を実行してください\");\n }\n } catch (error) {\n // プロンプトがキャンセルされた場合など\n logger.info(\"direnv allow をスキップしました\");\n }\n}\n","import { join } from \"node:path\";\nimport type { ToolSetupOptions } from \"../../types/index.js\";\nimport { writeWithStrategy } from \"../../utils/fs.js\";\nimport { addDependencies, addScripts } from \"../../utils/package-json.js\";\n\nconst ENV_EXAMPLE_CONTENT = `# Environment variables template\n# Copy this file to .env and fill in the values\n\n# Database\nDATABASE_URL=\"postgresql://user:password@localhost:25432/dbname\"\n\n# NextAuth\nNEXTAUTH_URL=\"http://localhost:3000\"\nNEXTAUTH_SECRET=\"your-secret-here\"\n\n# OAuth (if using)\n# GOOGLE_CLIENT_ID=\"\"\n# GOOGLE_CLIENT_SECRET=\"\"\n# GITHUB_CLIENT_ID=\"\"\n# GITHUB_CLIENT_SECRET=\"\"\n`;\n\n/**\n * dotenvxのセットアップを実行する\n *\n * AC-004-1: package.jsonに依存関係が追加される\n * AC-004-2: npm scriptsにdotenvxコマンドが追加される\n * AC-004-3: .env.example が生成される\n */\nexport function setupDotenvx(options: ToolSetupOptions): void {\n const { targetDir, conflictStrategy } = options;\n\n addDependencies(targetDir, {\n \"@dotenvx/dotenvx\": \"^1.29.0\",\n });\n\n addScripts(targetDir, {\n \"env:encrypt\": \"dotenvx encrypt\",\n \"env:decrypt\": \"dotenvx decrypt\",\n });\n\n const envExamplePath = join(targetDir, \".env.example\");\n writeWithStrategy(envExamplePath, ENV_EXAMPLE_CONTENT, conflictStrategy);\n}\n","import { readFileSync, writeFileSync } from \"node:fs\";\nimport { join } from \"node:path\";\nimport { fileExists } from \"./fs.js\";\n\ntype PackageJson = {\n name?: string;\n version?: string;\n scripts?: Record<string, string>;\n dependencies?: Record<string, string>;\n devDependencies?: Record<string, string>;\n volta?: {\n node?: string;\n pnpm?: string;\n };\n \"lint-staged\"?: Record<string, string | string[]>;\n [key: string]: unknown;\n};\n\n/**\n * package.jsonを読み込む\n */\nexport function readPackageJson(targetDir: string): PackageJson {\n const packageJsonPath = join(targetDir, \"package.json\");\n\n if (!fileExists(packageJsonPath)) {\n return {};\n }\n\n const content = readFileSync(packageJsonPath, \"utf-8\");\n return JSON.parse(content) as PackageJson;\n}\n\n/**\n * package.jsonに書き込む\n */\nexport function writePackageJson(targetDir: string, data: PackageJson): void {\n const packageJsonPath = join(targetDir, \"package.json\");\n const content = JSON.stringify(data, null, 2);\n writeFileSync(packageJsonPath, `${content}\\n`, \"utf-8\");\n}\n\n/**\n * package.jsonにスクリプトを追加する\n */\nexport function addScripts(\n targetDir: string,\n scripts: Record<string, string>\n): void {\n const pkg = readPackageJson(targetDir);\n pkg.scripts = { ...pkg.scripts, ...scripts };\n writePackageJson(targetDir, pkg);\n}\n\n/**\n * package.jsonに依存関係を追加する\n */\nexport function addDependencies(\n targetDir: string,\n dependencies: Record<string, string>,\n dev = false\n): void {\n const pkg = readPackageJson(targetDir);\n\n if (dev) {\n pkg.devDependencies = { ...pkg.devDependencies, ...dependencies };\n } else {\n pkg.dependencies = { ...pkg.dependencies, ...dependencies };\n }\n\n writePackageJson(targetDir, pkg);\n}\n\n/**\n * package.jsonにVoltaフィールドを追加する\n */\nexport function addVoltaField(\n targetDir: string,\n nodeVersion: string,\n pnpmVersion: string\n): void {\n const pkg = readPackageJson(targetDir);\n pkg.volta = {\n node: nodeVersion,\n pnpm: pnpmVersion,\n };\n writePackageJson(targetDir, pkg);\n}\n\n/**\n * package.jsonにlint-staged設定を追加する\n */\nexport function addLintStaged(\n targetDir: string,\n config: Record<string, string | string[]>\n): void {\n const pkg = readPackageJson(targetDir);\n pkg[\"lint-staged\"] = { ...pkg[\"lint-staged\"], ...config };\n writePackageJson(targetDir, pkg);\n}\n","import { join } from \"node:path\";\nimport type { ToolSetupOptions } from \"../../types/index.js\";\nimport { writeWithStrategy } from \"../../utils/fs.js\";\nimport { addVoltaField } from \"../../utils/package-json.js\";\n\nconst NODE_VERSION = \"22.16.0\";\nconst PNPM_VERSION = \"9.15.0\";\n\nconst NODE_VERSION_CONTENT = `${NODE_VERSION}\n`;\n\n/**\n * Voltaのセットアップを実行する\n *\n * AC-005-1: package.jsonにvoltaフィールドが追加される\n * AC-005-2: .node-version ファイルが生成される\n */\nexport function setupVolta(options: ToolSetupOptions): void {\n const { targetDir, conflictStrategy } = options;\n\n addVoltaField(targetDir, NODE_VERSION, PNPM_VERSION);\n\n const nodeVersionPath = join(targetDir, \".node-version\");\n writeWithStrategy(nodeVersionPath, NODE_VERSION_CONTENT, conflictStrategy);\n}\n","import { join } from \"node:path\";\nimport type { ToolSetupOptions } from \"../../types/index.js\";\nimport { writeWithStrategy, ensureDir } from \"../../utils/fs.js\";\nimport { addDependencies, addScripts } from \"../../utils/package-json.js\";\n\nconst BIOME_CONFIG = `{\n \"$schema\": \"https://biomejs.dev/schemas/1.9.4/schema.json\",\n \"vcs\": {\n \"enabled\": true,\n \"clientKind\": \"git\",\n \"useIgnoreFile\": true\n },\n \"files\": {\n \"ignoreUnknown\": false,\n \"ignore\": [\"node_modules\", \"dist\", \".next\", \"out\", \"build\", \"coverage\"]\n },\n \"formatter\": {\n \"enabled\": true,\n \"indentStyle\": \"space\",\n \"indentWidth\": 2,\n \"lineEnding\": \"lf\",\n \"lineWidth\": 100\n },\n \"organizeImports\": {\n \"enabled\": true\n },\n \"linter\": {\n \"enabled\": true,\n \"rules\": {\n \"recommended\": true\n }\n },\n \"javascript\": {\n \"formatter\": {\n \"quoteStyle\": \"double\",\n \"trailingCommas\": \"es5\",\n \"semicolons\": \"always\",\n \"arrowParentheses\": \"always\"\n }\n }\n}\n`;\n\nconst VSCODE_SETTINGS = `{\n \"editor.defaultFormatter\": \"biomejs.biome\",\n \"editor.formatOnSave\": true,\n \"editor.codeActionsOnSave\": {\n \"quickfix.biome\": \"explicit\",\n \"source.organizeImports.biome\": \"explicit\"\n },\n \"[javascript]\": {\n \"editor.defaultFormatter\": \"biomejs.biome\"\n },\n \"[typescript]\": {\n \"editor.defaultFormatter\": \"biomejs.biome\"\n },\n \"[json]\": {\n \"editor.defaultFormatter\": \"biomejs.biome\"\n }\n}\n`;\n\n/**\n * Biomeのセットアップを実行する(--setupモードのみ)\n *\n * AC-006-1: biome.json が生成される\n * AC-006-2: package.jsonにlint/formatスクリプトが追加される\n * AC-006-3: VSCode設定が追加される\n */\nexport function setupBiome(options: ToolSetupOptions): void {\n const { targetDir, conflictStrategy } = options;\n\n const biomeConfigPath = join(targetDir, \"biome.json\");\n writeWithStrategy(biomeConfigPath, BIOME_CONFIG, conflictStrategy);\n\n addDependencies(\n targetDir,\n {\n \"@biomejs/biome\": \"^1.9.4\",\n },\n true\n );\n\n addScripts(targetDir, {\n lint: \"biome lint .\",\n \"lint:fix\": \"biome lint --write .\",\n format: \"biome format .\",\n \"format:fix\": \"biome format --write .\",\n });\n\n const vscodeDir = join(targetDir, \".vscode\");\n ensureDir(vscodeDir);\n\n const vscodeSettingsPath = join(vscodeDir, \"settings.json\");\n writeWithStrategy(vscodeSettingsPath, VSCODE_SETTINGS, conflictStrategy);\n}\n","import { join } from \"node:path\";\nimport { writeFileSync } from \"node:fs\";\nimport type { ToolSetupOptions } from \"../../types/index.js\";\nimport { ensureDir } from \"../../utils/fs.js\";\nimport { addDependencies, addScripts, addLintStaged } from \"../../utils/package-json.js\";\n\nconst PRE_COMMIT_HOOK = `#!/usr/bin/env sh\n. \"$(dirname -- \"$0\")/_/husky.sh\"\n\npnpm lint-staged\n`;\n\n/**\n * Husky + lint-stagedのセットアップを実行する(--setupモードのみ)\n *\n * AC-007-1: .husky/ ディレクトリが生成される\n * AC-007-2: pre-commitフックが設定される\n * AC-007-3: lint-staged設定が追加される\n */\nexport function setupHusky(options: ToolSetupOptions): void {\n const { targetDir } = options;\n\n addDependencies(\n targetDir,\n {\n husky: \"^9.1.7\",\n \"lint-staged\": \"^15.2.11\",\n },\n true\n );\n\n addScripts(targetDir, {\n prepare: \"husky\",\n });\n\n addLintStaged(targetDir, {\n \"*.{js,jsx,ts,tsx}\": [\"biome format --write\", \"biome lint --write\"],\n \"*.{json,md,yml,yaml}\": [\"biome format --write\"],\n });\n\n const huskyDir = join(targetDir, \".husky\");\n ensureDir(huskyDir);\n\n const preCommitPath = join(huskyDir, \"pre-commit\");\n writeFileSync(preCommitPath, PRE_COMMIT_HOOK, { mode: 0o755 });\n}\n"],"mappings":"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","names":["readFileSync","fileURLToPath","dirname","join","existsSync","ora","dirname","join","readFileSync","writeFileSync","existsSync","__filename","__dirname","dirname","join","error","chalk","inquirer","inquirer","error","chalk","existsSync","error","ora","existsSync","join","ora","inquirer","join","inquirer","join","inquirer","error","join","readFileSync","writeFileSync","join","packageJsonPath","join","readFileSync","writeFileSync","join","join","join","join","join","join","writeFileSync","join","writeFileSync","packageJsonPath","join","existsSync","ora","error","__filename","fileURLToPath","__dirname","dirname","join","readFileSync"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "create-einja-app",
3
- "version": "0.1.1",
3
+ "version": "0.1.2",
4
4
  "description": "CLI tool to create new projects with Einja Management Template",
5
5
  "type": "module",
6
6
  "bin": {
@@ -403,11 +403,11 @@ export const { handlers, signIn, signOut, auth } = NextAuth(authOptions);
403
403
 
404
404
  | 原本 | コピー先 | 備考 |
405
405
  |-----|---------|------|
406
- | `.claude/agents/einja/` | `presets/minimal/.claude/agents/einja/` | 単純コピー |
407
- | `.claude/commands/einja/` | `presets/minimal/.claude/commands/einja/` | 単純コピー |
408
- | `.claude/skills/einja-*/` | `presets/minimal/.claude/skills/einja-*/` | 単純コピー |
409
- | `.claude/hooks/einja/` | `presets/minimal/.claude/hooks/einja/` | 単純コピー |
410
- | `.claude/settings.json` | `presets/minimal/.claude/settings.json` | 単純コピー |
406
+ | `.claude/agents/einja/` | `presets/default/.claude/agents/einja/` | 単純コピー |
407
+ | `.claude/commands/einja/` | `presets/default/.claude/commands/einja/` | 単純コピー |
408
+ | `.claude/skills/einja-*/` | `presets/default/.claude/skills/einja-*/` | 単純コピー |
409
+ | `.claude/hooks/einja/` | `presets/default/.claude/hooks/einja/` | 単純コピー |
410
+ | `.claude/settings.json` | `presets/default/.claude/settings.json` | 単純コピー |
411
411
  | `docs/einja/steering/` | `scaffolds/steering/` | 単純コピー |
412
412
  | `CLAUDE.md` | `scaffolds/CLAUDE.md.template` | **変換生成** |
413
413
 
@@ -0,0 +1,57 @@
1
+ /**
2
+ * userRoutes.ts
3
+ *
4
+ * Hono APIルート定義(Presentation層)
5
+ * ユーザー一覧・詳細取得エンドポイント
6
+ */
7
+
8
+ import { Hono } from "hono";
9
+ import { zValidator } from "@hono/zod-validator";
10
+ import {
11
+ userListQuerySchema,
12
+ userIdParamSchema,
13
+ } from "{{packageName}}/server-core/domain/validators/user";
14
+ import { userUseCases } from "@web/application/use-cases/UserUseCases";
15
+
16
+ /**
17
+ * ユーザーAPI ルート
18
+ *
19
+ * 重要: メソッドチェーン形式で定義(型推論のため)
20
+ */
21
+ export const userRoutes = new Hono()
22
+ .get("/", zValidator("query", userListQuerySchema), async (c) => {
23
+ const query = c.req.valid("query");
24
+
25
+ const result = await userUseCases.list(
26
+ {
27
+ search: query.search,
28
+ status: query.status,
29
+ role: query.role,
30
+ },
31
+ {
32
+ page: query.page,
33
+ limit: query.limit,
34
+ }
35
+ );
36
+
37
+ if (!result.isSuccess) {
38
+ return c.json({ error: result.error.message }, 500);
39
+ }
40
+
41
+ return c.json(result.value);
42
+ })
43
+ .get("/:id", zValidator("param", userIdParamSchema), async (c) => {
44
+ const { id } = c.req.valid("param");
45
+
46
+ const result = await userUseCases.getById(id);
47
+
48
+ if (!result.isSuccess) {
49
+ return c.json({ error: result.error.message }, 500);
50
+ }
51
+
52
+ if (!result.value) {
53
+ return c.json({ error: "User not found" }, 404);
54
+ }
55
+
56
+ return c.json(result.value);
57
+ });
@@ -55,9 +55,14 @@ function formatDate(dateString: string | null): string {
55
55
  }
56
56
 
57
57
  /**
58
- * テーブルの列定義
58
+ * テーブルの列定義を生成
59
59
  */
60
- const columns: ColumnDef<UserListItem>[] = [
60
+ function createColumns(
61
+ onView?: (userId: string) => void,
62
+ onEdit?: (userId: string) => void,
63
+ onDelete?: (userId: string) => void
64
+ ): ColumnDef<UserListItem>[] {
65
+ return [
61
66
  {
62
67
  accessorKey: "name",
63
68
  header: ({ column }) => {
@@ -159,16 +164,16 @@ const columns: ColumnDef<UserListItem>[] = [
159
164
  </Button>
160
165
  </DropdownMenuTrigger>
161
166
  <DropdownMenuContent align="end">
162
- <DropdownMenuItem onClick={() => console.log("詳細表示:", user.id)}>
167
+ <DropdownMenuItem onClick={() => onView?.(user.id)}>
163
168
  <Eye className="mr-2 h-4 w-4" />
164
169
  詳細表示
165
170
  </DropdownMenuItem>
166
- <DropdownMenuItem onClick={() => console.log("編集:", user.id)}>
171
+ <DropdownMenuItem onClick={() => onEdit?.(user.id)}>
167
172
  <Edit className="mr-2 h-4 w-4" />
168
173
  編集
169
174
  </DropdownMenuItem>
170
175
  <DropdownMenuItem
171
- onClick={() => console.log("削除:", user.id)}
176
+ onClick={() => onDelete?.(user.id)}
172
177
  className="text-destructive"
173
178
  >
174
179
  <Trash2 className="mr-2 h-4 w-4" />
@@ -179,16 +184,22 @@ const columns: ColumnDef<UserListItem>[] = [
179
184
  );
180
185
  },
181
186
  },
182
- ];
187
+ ];
188
+ }
183
189
 
184
190
  interface UserTableProps {
185
191
  users: readonly UserListItem[];
192
+ onView?: (userId: string) => void;
193
+ onEdit?: (userId: string) => void;
194
+ onDelete?: (userId: string) => void;
186
195
  }
187
196
 
188
197
  /**
189
198
  * ユーザーテーブルコンポーネント
190
199
  */
191
- export function UserTable({ users }: UserTableProps) {
200
+ export function UserTable({ users, onView, onEdit, onDelete }: UserTableProps) {
201
+ const columns = createColumns(onView, onEdit, onDelete);
202
+
192
203
  return (
193
204
  <DataTable
194
205
  columns={columns}