kybernus 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +321 -0
- package/dist/cli/commands/init.d.ts +12 -0
- package/dist/cli/commands/init.d.ts.map +1 -0
- package/dist/cli/commands/init.js +71 -0
- package/dist/cli/commands/init.js.map +1 -0
- package/dist/cli/commands/login.d.ts +6 -0
- package/dist/cli/commands/login.d.ts.map +1 -0
- package/dist/cli/commands/login.js +42 -0
- package/dist/cli/commands/login.js.map +1 -0
- package/dist/cli/commands/logout.d.ts +2 -0
- package/dist/cli/commands/logout.d.ts.map +1 -0
- package/dist/cli/commands/logout.js +22 -0
- package/dist/cli/commands/logout.js.map +1 -0
- package/dist/cli/commands/register.d.ts +2 -0
- package/dist/cli/commands/register.d.ts.map +1 -0
- package/dist/cli/commands/register.js +69 -0
- package/dist/cli/commands/register.js.map +1 -0
- package/dist/cli/commands/status.d.ts +2 -0
- package/dist/cli/commands/status.d.ts.map +1 -0
- package/dist/cli/commands/status.js +46 -0
- package/dist/cli/commands/status.js.map +1 -0
- package/dist/cli/commands/upgrade.d.ts +2 -0
- package/dist/cli/commands/upgrade.d.ts.map +1 -0
- package/dist/cli/commands/upgrade.js +62 -0
- package/dist/cli/commands/upgrade.js.map +1 -0
- package/dist/cli/prompts/wizard.d.ts +3 -0
- package/dist/cli/prompts/wizard.d.ts.map +1 -0
- package/dist/cli/prompts/wizard.js +121 -0
- package/dist/cli/prompts/wizard.js.map +1 -0
- package/dist/cli/services/AnalyticsClient.d.ts +11 -0
- package/dist/cli/services/AnalyticsClient.d.ts.map +1 -0
- package/dist/cli/services/AnalyticsClient.js +32 -0
- package/dist/cli/services/AnalyticsClient.js.map +1 -0
- package/dist/core/ai/documentation-generator.d.ts +36 -0
- package/dist/core/ai/documentation-generator.d.ts.map +1 -0
- package/dist/core/ai/documentation-generator.js +111 -0
- package/dist/core/ai/documentation-generator.js.map +1 -0
- package/dist/core/ai/gemini-service.d.ts +17 -0
- package/dist/core/ai/gemini-service.d.ts.map +1 -0
- package/dist/core/ai/gemini-service.js +68 -0
- package/dist/core/ai/gemini-service.js.map +1 -0
- package/dist/core/ai/prompts/documentation-prompts.d.ts +17 -0
- package/dist/core/ai/prompts/documentation-prompts.d.ts.map +1 -0
- package/dist/core/ai/prompts/documentation-prompts.js +195 -0
- package/dist/core/ai/prompts/documentation-prompts.js.map +1 -0
- package/dist/core/auth/license-validator.d.ts +33 -0
- package/dist/core/auth/license-validator.d.ts.map +1 -0
- package/dist/core/auth/license-validator.js +81 -0
- package/dist/core/auth/license-validator.js.map +1 -0
- package/dist/core/config/config-manager.d.ts +24 -0
- package/dist/core/config/config-manager.d.ts.map +1 -0
- package/dist/core/config/config-manager.js +56 -0
- package/dist/core/config/config-manager.js.map +1 -0
- package/dist/core/generator/context-builder.d.ts +10 -0
- package/dist/core/generator/context-builder.d.ts.map +1 -0
- package/dist/core/generator/context-builder.js +43 -0
- package/dist/core/generator/context-builder.js.map +1 -0
- package/dist/core/generator/project.d.ts +42 -0
- package/dist/core/generator/project.d.ts.map +1 -0
- package/dist/core/generator/project.js +278 -0
- package/dist/core/generator/project.js.map +1 -0
- package/dist/core/templates/engine.d.ts +25 -0
- package/dist/core/templates/engine.d.ts.map +1 -0
- package/dist/core/templates/engine.js +78 -0
- package/dist/core/templates/engine.js.map +1 -0
- package/dist/core/templates/helpers.d.ts +6 -0
- package/dist/core/templates/helpers.d.ts.map +1 -0
- package/dist/core/templates/helpers.js +63 -0
- package/dist/core/templates/helpers.js.map +1 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +48 -0
- package/dist/index.js.map +1 -0
- package/dist/models/config.d.ts +38 -0
- package/dist/models/config.d.ts.map +1 -0
- package/dist/models/config.js +2 -0
- package/dist/models/config.js.map +1 -0
- package/package.json +66 -0
- package/templates/java-spring/free/mvc/.gitignore.hbs +39 -0
- package/templates/java-spring/free/mvc/README.md.hbs +116 -0
- package/templates/java-spring/free/mvc/docker-compose.yml.hbs +18 -0
- package/templates/java-spring/free/mvc/pom.xml.hbs +92 -0
- package/templates/java-spring/free/mvc/src/main/java/{{packagePath}}/config/GlobalExceptionHandler.java.hbs +39 -0
- package/templates/java-spring/free/mvc/src/main/java/{{packagePath}}/config/WebConfig.java.hbs +30 -0
- package/templates/java-spring/free/mvc/src/main/java/{{packagePath}}/controller/HealthController.java.hbs +30 -0
- package/templates/java-spring/free/mvc/src/main/java/{{packagePath}}/model/.gitkeep +0 -0
- package/templates/java-spring/free/mvc/src/main/java/{{packagePath}}/repository/.gitkeep +0 -0
- package/templates/java-spring/free/mvc/src/main/java/{{packagePath}}/service/.gitkeep +0 -0
- package/templates/java-spring/free/mvc/src/main/java/{{packagePath}}/{{projectNamePascalCase}}Application.java.hbs +13 -0
- package/templates/java-spring/free/mvc/src/main/resources/application.yml.hbs +32 -0
- package/templates/java-spring/free/mvc/src/test/java/{{packagePath}}/{{projectNamePascalCase}}ApplicationTests.java.hbs +13 -0
- package/templates/java-spring/free/mvc/src/test/resources/application.yml.hbs +10 -0
- package/templates/java-spring/free/mvc/template.json +14 -0
- package/templates/java-spring/pro/clean/.github/workflows/ci-cd.yml.hbs +88 -0
- package/templates/java-spring/pro/clean/Dockerfile.hbs +45 -0
- package/templates/java-spring/pro/clean/README.md.hbs +31 -0
- package/templates/java-spring/pro/clean/docker-compose.yml.hbs +18 -0
- package/templates/java-spring/pro/clean/infra/main.tf.hbs +83 -0
- package/templates/java-spring/pro/clean/infra/modules/ecs/main.tf.hbs +54 -0
- package/templates/java-spring/pro/clean/infra/modules/rds/main.tf.hbs +88 -0
- package/templates/java-spring/pro/clean/infra/modules/vpc/main.tf.hbs +107 -0
- package/templates/java-spring/pro/clean/pom.xml.hbs +130 -0
- package/templates/java-spring/pro/clean/src/main/java/{{packagePath}}/application/service/AuthService.java.hbs +36 -0
- package/templates/java-spring/pro/clean/src/main/java/{{packagePath}}/domain/entity/User.java.hbs +77 -0
- package/templates/java-spring/pro/clean/src/main/java/{{packagePath}}/domain/repository/UserRepository.java.hbs +15 -0
- package/templates/java-spring/pro/clean/src/main/java/{{packagePath}}/domain/usecase/LoginUserUseCase.java.hbs +36 -0
- package/templates/java-spring/pro/clean/src/main/java/{{packagePath}}/domain/usecase/RegisterUserUseCase.java.hbs +46 -0
- package/templates/java-spring/pro/clean/src/main/java/{{packagePath}}/infrastructure/persistence/InMemoryUserRepository.java.hbs +41 -0
- package/templates/java-spring/pro/clean/src/main/java/{{packagePath}}/infrastructure/security/SecurityAdapters.java.hbs +53 -0
- package/templates/java-spring/pro/clean/src/main/java/{{packagePath}}/infrastructure/web/controller/AuthController.java.hbs +41 -0
- package/templates/java-spring/pro/clean/src/main/java/{{packagePath}}/{{projectNamePascalCase}}Application.java.hbs +14 -0
- package/templates/java-spring/pro/hexagonal/.github/workflows/ci-cd.yml.hbs +88 -0
- package/templates/java-spring/pro/hexagonal/Dockerfile.hbs +45 -0
- package/templates/java-spring/pro/hexagonal/README.md.hbs +38 -0
- package/templates/java-spring/pro/hexagonal/docker-compose.yml.hbs +18 -0
- package/templates/java-spring/pro/hexagonal/infra/main.tf.hbs +83 -0
- package/templates/java-spring/pro/hexagonal/infra/modules/ecs/main.tf.hbs +54 -0
- package/templates/java-spring/pro/hexagonal/infra/modules/rds/main.tf.hbs +88 -0
- package/templates/java-spring/pro/hexagonal/infra/modules/vpc/main.tf.hbs +107 -0
- package/templates/java-spring/pro/hexagonal/pom.xml.hbs +130 -0
- package/templates/java-spring/pro/hexagonal/src/main/java/{{packagePath}}/application/service/AuthService.java.hbs +36 -0
- package/templates/java-spring/pro/hexagonal/src/main/java/{{packagePath}}/domain/entity/User.java.hbs +77 -0
- package/templates/java-spring/pro/hexagonal/src/main/java/{{packagePath}}/domain/repository/UserRepository.java.hbs +15 -0
- package/templates/java-spring/pro/hexagonal/src/main/java/{{packagePath}}/domain/usecase/LoginUserUseCase.java.hbs +36 -0
- package/templates/java-spring/pro/hexagonal/src/main/java/{{packagePath}}/domain/usecase/RegisterUserUseCase.java.hbs +46 -0
- package/templates/java-spring/pro/hexagonal/src/main/java/{{packagePath}}/infrastructure/persistence/InMemoryUserRepository.java.hbs +41 -0
- package/templates/java-spring/pro/hexagonal/src/main/java/{{packagePath}}/infrastructure/security/SecurityAdapters.java.hbs +53 -0
- package/templates/java-spring/pro/hexagonal/src/main/java/{{packagePath}}/infrastructure/web/controller/AuthController.java.hbs +41 -0
- package/templates/java-spring/pro/hexagonal/src/main/java/{{packagePath}}/{{projectNamePascalCase}}Application.java.hbs +14 -0
- package/templates/java-spring/pro/mvc/.github/workflows/ci-cd.yml.hbs +88 -0
- package/templates/java-spring/pro/mvc/Dockerfile.hbs +45 -0
- package/templates/java-spring/pro/mvc/README.md.hbs +116 -0
- package/templates/java-spring/pro/mvc/docker-compose.yml.hbs +18 -0
- package/templates/java-spring/pro/mvc/infra/main.tf.hbs +83 -0
- package/templates/java-spring/pro/mvc/infra/modules/ecs/main.tf.hbs +54 -0
- package/templates/java-spring/pro/mvc/infra/modules/rds/main.tf.hbs +88 -0
- package/templates/java-spring/pro/mvc/infra/modules/vpc/main.tf.hbs +107 -0
- package/templates/java-spring/pro/mvc/pom.xml.hbs +130 -0
- package/templates/java-spring/pro/mvc/src/main/java/{{packagePath}}/config/GlobalExceptionHandler.java.hbs +39 -0
- package/templates/java-spring/pro/mvc/src/main/java/{{packagePath}}/config/SecurityConfig.java.hbs +44 -0
- package/templates/java-spring/pro/mvc/src/main/java/{{packagePath}}/config/WebConfig.java.hbs +30 -0
- package/templates/java-spring/pro/mvc/src/main/java/{{packagePath}}/controller/AuthController.java.hbs +69 -0
- package/templates/java-spring/pro/mvc/src/main/java/{{packagePath}}/controller/HealthController.java.hbs +30 -0
- package/templates/java-spring/pro/mvc/src/main/java/{{packagePath}}/controller/PaymentsController.java.hbs +49 -0
- package/templates/java-spring/pro/mvc/src/main/java/{{packagePath}}/dto/AuthRequest.java.hbs +3 -0
- package/templates/java-spring/pro/mvc/src/main/java/{{packagePath}}/dto/AuthResponse.java.hbs +3 -0
- package/templates/java-spring/pro/mvc/src/main/java/{{packagePath}}/model/.gitkeep +0 -0
- package/templates/java-spring/pro/mvc/src/main/java/{{packagePath}}/repository/.gitkeep +0 -0
- package/templates/java-spring/pro/mvc/src/main/java/{{packagePath}}/security/JwtAuthenticationFilter.java.hbs +56 -0
- package/templates/java-spring/pro/mvc/src/main/java/{{packagePath}}/security/JwtTokenProvider.java.hbs +59 -0
- package/templates/java-spring/pro/mvc/src/main/java/{{packagePath}}/service/.gitkeep +0 -0
- package/templates/java-spring/pro/mvc/src/main/java/{{packagePath}}/service/StripeService.java.hbs +67 -0
- package/templates/java-spring/pro/mvc/src/main/java/{{packagePath}}/{{projectNamePascalCase}}Application.java.hbs +13 -0
- package/templates/java-spring/pro/mvc/src/main/resources/application.yml.hbs +32 -0
- package/templates/java-spring/pro/mvc/src/test/java/{{packagePath}}/{{projectNamePascalCase}}ApplicationTests.java.hbs +13 -0
- package/templates/java-spring/pro/mvc/src/test/resources/application.yml.hbs +10 -0
- package/templates/java-spring/pro/mvc/template.json +14 -0
- package/templates/nestjs/free/mvc/README.md.hbs +28 -0
- package/templates/nestjs/free/mvc/package.json.hbs +29 -0
- package/templates/nestjs/free/mvc/src/app.module.ts.hbs +13 -0
- package/templates/nestjs/free/mvc/src/controllers/health.controller.ts.hbs +9 -0
- package/templates/nestjs/free/mvc/src/controllers/items.controller.ts.hbs +32 -0
- package/templates/nestjs/free/mvc/src/main.ts.hbs +17 -0
- package/templates/nestjs/free/mvc/src/models/create-item.dto.ts.hbs +10 -0
- package/templates/nestjs/free/mvc/src/models/item.model.ts.hbs +6 -0
- package/templates/nestjs/free/mvc/src/modules/items.module.ts.hbs +9 -0
- package/templates/nestjs/free/mvc/src/services/items.service.ts.hbs +32 -0
- package/templates/nestjs/free/mvc/tsconfig.json.hbs +21 -0
- package/templates/nestjs/pro/clean/.env.example.hbs +19 -0
- package/templates/nestjs/pro/clean/.github/workflows/ci-cd.yml.hbs +88 -0
- package/templates/nestjs/pro/clean/Dockerfile.hbs +45 -0
- package/templates/nestjs/pro/clean/infra/main.tf.hbs +83 -0
- package/templates/nestjs/pro/clean/infra/modules/ecs/main.tf.hbs +54 -0
- package/templates/nestjs/pro/clean/infra/modules/rds/main.tf.hbs +88 -0
- package/templates/nestjs/pro/clean/infra/modules/vpc/main.tf.hbs +107 -0
- package/templates/nestjs/pro/clean/package.json.hbs +37 -0
- package/templates/nestjs/pro/clean/src/auth.module.ts.hbs +17 -0
- package/templates/nestjs/pro/clean/src/domain/entities/user.entity.ts.hbs +12 -0
- package/templates/nestjs/pro/clean/src/domain/repositories/user.repository.ts.hbs +6 -0
- package/templates/nestjs/pro/clean/src/domain/use-cases/register.use-case.ts.hbs +18 -0
- package/templates/nestjs/pro/clean/src/infrastructure/database/in-memory.repository.ts.hbs +17 -0
- package/templates/nestjs/pro/clean/src/infrastructure/http/auth.controller.ts.hbs +16 -0
- package/templates/nestjs/pro/clean/tsconfig.json.hbs +21 -0
- package/templates/nestjs/pro/hexagonal/.env.example.hbs +19 -0
- package/templates/nestjs/pro/hexagonal/.github/workflows/ci-cd.yml.hbs +88 -0
- package/templates/nestjs/pro/hexagonal/Dockerfile.hbs +45 -0
- package/templates/nestjs/pro/hexagonal/infra/main.tf.hbs +83 -0
- package/templates/nestjs/pro/hexagonal/infra/modules/ecs/main.tf.hbs +54 -0
- package/templates/nestjs/pro/hexagonal/infra/modules/rds/main.tf.hbs +88 -0
- package/templates/nestjs/pro/hexagonal/infra/modules/vpc/main.tf.hbs +107 -0
- package/templates/nestjs/pro/hexagonal/package.json.hbs +37 -0
- package/templates/nestjs/pro/hexagonal/src/adapters/inbound/http.adapter.ts.hbs +12 -0
- package/templates/nestjs/pro/hexagonal/src/adapters/outbound/persistence.adapter.ts.hbs +13 -0
- package/templates/nestjs/pro/hexagonal/src/auth.module.ts.hbs +19 -0
- package/templates/nestjs/pro/hexagonal/src/core/auth.service.ts.hbs +16 -0
- package/templates/nestjs/pro/hexagonal/src/core/domain/user.entity.ts.hbs +8 -0
- package/templates/nestjs/pro/hexagonal/src/core/ports/ports.ts.hbs +9 -0
- package/templates/nestjs/pro/hexagonal/tsconfig.json.hbs +21 -0
- package/templates/nestjs/pro/mvc/.env.example.hbs +19 -0
- package/templates/nestjs/pro/mvc/.github/workflows/ci-cd.yml.hbs +88 -0
- package/templates/nestjs/pro/mvc/Dockerfile.hbs +45 -0
- package/templates/nestjs/pro/mvc/README.md.hbs +28 -0
- package/templates/nestjs/pro/mvc/infra/main.tf.hbs +83 -0
- package/templates/nestjs/pro/mvc/infra/modules/ecs/main.tf.hbs +54 -0
- package/templates/nestjs/pro/mvc/infra/modules/rds/main.tf.hbs +88 -0
- package/templates/nestjs/pro/mvc/infra/modules/vpc/main.tf.hbs +107 -0
- package/templates/nestjs/pro/mvc/package.json.hbs +37 -0
- package/templates/nestjs/pro/mvc/src/app.module.ts.hbs +17 -0
- package/templates/nestjs/pro/mvc/src/auth/auth.controller.ts.hbs +35 -0
- package/templates/nestjs/pro/mvc/src/auth/auth.module.ts.hbs +25 -0
- package/templates/nestjs/pro/mvc/src/auth/auth.service.ts.hbs +55 -0
- package/templates/nestjs/pro/mvc/src/auth/jwt.strategy.ts.hbs +19 -0
- package/templates/nestjs/pro/mvc/src/controllers/health.controller.ts.hbs +9 -0
- package/templates/nestjs/pro/mvc/src/controllers/items.controller.ts.hbs +32 -0
- package/templates/nestjs/pro/mvc/src/main.ts.hbs +17 -0
- package/templates/nestjs/pro/mvc/src/models/create-item.dto.ts.hbs +10 -0
- package/templates/nestjs/pro/mvc/src/models/item.model.ts.hbs +6 -0
- package/templates/nestjs/pro/mvc/src/modules/items.module.ts.hbs +9 -0
- package/templates/nestjs/pro/mvc/src/payments/payments.controller.ts.hbs +26 -0
- package/templates/nestjs/pro/mvc/src/payments/payments.module.ts.hbs +11 -0
- package/templates/nestjs/pro/mvc/src/payments/payments.service.ts.hbs +43 -0
- package/templates/nestjs/pro/mvc/src/services/items.service.ts.hbs +32 -0
- package/templates/nestjs/pro/mvc/tsconfig.json.hbs +21 -0
- package/templates/nextjs/free/default/.env.example.hbs +1 -0
- package/templates/nextjs/free/default/.gitignore.hbs +8 -0
- package/templates/nextjs/free/default/README.md.hbs +96 -0
- package/templates/nextjs/free/default/docker-compose.yml.hbs +18 -0
- package/templates/nextjs/free/default/next.config.js.hbs +4 -0
- package/templates/nextjs/free/default/package.json.hbs +32 -0
- package/templates/nextjs/free/default/postcss.config.js.hbs +6 -0
- package/templates/nextjs/free/default/prisma/schema.prisma.hbs +18 -0
- package/templates/nextjs/free/default/public/.gitkeep +0 -0
- package/templates/nextjs/free/default/src/app/api/health/route.ts.hbs +9 -0
- package/templates/nextjs/free/default/src/app/globals.css.hbs +3 -0
- package/templates/nextjs/free/default/src/app/layout.tsx.hbs +22 -0
- package/templates/nextjs/free/default/src/app/page.tsx.hbs +38 -0
- package/templates/nextjs/free/default/src/components/.gitkeep +0 -0
- package/templates/nextjs/free/default/src/lib/prisma.ts.hbs +13 -0
- package/templates/nextjs/free/default/src/proxy.ts.hbs +22 -0
- package/templates/nextjs/free/default/tailwind.config.ts.hbs +15 -0
- package/templates/nextjs/free/default/template.json +18 -0
- package/templates/nextjs/free/default/tsconfig.json.hbs +23 -0
- package/templates/nextjs/pro/default/.env.example.hbs +20 -0
- package/templates/nextjs/pro/default/.github/workflows/ci-cd.yml.hbs +88 -0
- package/templates/nextjs/pro/default/Dockerfile.hbs +45 -0
- package/templates/nextjs/pro/default/README.md.hbs +96 -0
- package/templates/nextjs/pro/default/docker-compose.yml.hbs +18 -0
- package/templates/nextjs/pro/default/infra/main.tf.hbs +83 -0
- package/templates/nextjs/pro/default/infra/modules/ecs/main.tf.hbs +54 -0
- package/templates/nextjs/pro/default/infra/modules/rds/main.tf.hbs +88 -0
- package/templates/nextjs/pro/default/infra/modules/vpc/main.tf.hbs +107 -0
- package/templates/nextjs/pro/default/next.config.js.hbs +4 -0
- package/templates/nextjs/pro/default/package.json.hbs +34 -0
- package/templates/nextjs/pro/default/postcss.config.js.hbs +6 -0
- package/templates/nextjs/pro/default/prisma/schema.prisma.hbs +18 -0
- package/templates/nextjs/pro/default/public/.gitkeep +0 -0
- package/templates/nextjs/pro/default/src/app/api/auth/[...nextauth]/route.ts.hbs +61 -0
- package/templates/nextjs/pro/default/src/app/api/checkout/route.ts.hbs +30 -0
- package/templates/nextjs/pro/default/src/app/api/health/route.ts.hbs +9 -0
- package/templates/nextjs/pro/default/src/app/api/webhook/route.ts.hbs +51 -0
- package/templates/nextjs/pro/default/src/app/dashboard/page.tsx.hbs +52 -0
- package/templates/nextjs/pro/default/src/app/globals.css.hbs +3 -0
- package/templates/nextjs/pro/default/src/app/layout.tsx.hbs +22 -0
- package/templates/nextjs/pro/default/src/app/page.tsx.hbs +38 -0
- package/templates/nextjs/pro/default/src/components/.gitkeep +0 -0
- package/templates/nextjs/pro/default/src/components/AuthButton.tsx.hbs +34 -0
- package/templates/nextjs/pro/default/src/components/Providers.tsx.hbs +7 -0
- package/templates/nextjs/pro/default/src/lib/prisma.ts.hbs +13 -0
- package/templates/nextjs/pro/default/src/proxy.ts.hbs +22 -0
- package/templates/nextjs/pro/default/tailwind.config.ts.hbs +15 -0
- package/templates/nextjs/pro/default/template.json +18 -0
- package/templates/nextjs/pro/default/tsconfig.json.hbs +40 -0
- package/templates/nodejs-express/free/mvc/.env.example.hbs +3 -0
- package/templates/nodejs-express/free/mvc/.gitignore.hbs +6 -0
- package/templates/nodejs-express/free/mvc/README.md.hbs +128 -0
- package/templates/nodejs-express/free/mvc/docker-compose.yml.hbs +18 -0
- package/templates/nodejs-express/free/mvc/package.json.hbs +39 -0
- package/templates/nodejs-express/free/mvc/src/app.ts.hbs +29 -0
- package/templates/nodejs-express/free/mvc/src/config/database.ts.hbs +10 -0
- package/templates/nodejs-express/free/mvc/src/controllers/healthController.ts.hbs +20 -0
- package/templates/nodejs-express/free/mvc/src/index.ts.hbs +12 -0
- package/templates/nodejs-express/free/mvc/src/middleware/errorHandler.ts.hbs +22 -0
- package/templates/nodejs-express/free/mvc/src/models/.gitkeep +0 -0
- package/templates/nodejs-express/free/mvc/src/routes/index.ts.hbs +14 -0
- package/templates/nodejs-express/free/mvc/src/services/.gitkeep +0 -0
- package/templates/nodejs-express/free/mvc/template.json +18 -0
- package/templates/nodejs-express/free/mvc/tsconfig.json.hbs +18 -0
- package/templates/nodejs-express/pro/clean/.env.example.hbs +19 -0
- package/templates/nodejs-express/pro/clean/.github/workflows/ci-cd.yml.hbs +88 -0
- package/templates/nodejs-express/pro/clean/Dockerfile.hbs +45 -0
- package/templates/nodejs-express/pro/clean/README.md.hbs +41 -0
- package/templates/nodejs-express/pro/clean/docker-compose.yml.hbs +18 -0
- package/templates/nodejs-express/pro/clean/infra/main.tf.hbs +83 -0
- package/templates/nodejs-express/pro/clean/infra/modules/ecs/main.tf.hbs +54 -0
- package/templates/nodejs-express/pro/clean/infra/modules/rds/main.tf.hbs +88 -0
- package/templates/nodejs-express/pro/clean/infra/modules/vpc/main.tf.hbs +107 -0
- package/templates/nodejs-express/pro/clean/package.json.hbs +55 -0
- package/templates/nodejs-express/pro/clean/src/application/services/AuthService.ts.hbs +66 -0
- package/templates/nodejs-express/pro/clean/src/domain/entities/User.ts.hbs +38 -0
- package/templates/nodejs-express/pro/clean/src/domain/repositories/IUserRepository.ts.hbs +13 -0
- package/templates/nodejs-express/pro/clean/src/domain/usecases/LoginUserUseCase.ts.hbs +39 -0
- package/templates/nodejs-express/pro/clean/src/domain/usecases/RegisterUserUseCase.ts.hbs +51 -0
- package/templates/nodejs-express/pro/clean/src/index.ts.hbs +40 -0
- package/templates/nodejs-express/pro/clean/src/infrastructure/database/InMemoryUserRepository.ts.hbs +46 -0
- package/templates/nodejs-express/pro/clean/src/infrastructure/http/controllers/AuthController.ts.hbs +45 -0
- package/templates/nodejs-express/pro/clean/src/infrastructure/http/middlewares/AuthMiddleware.ts.hbs +27 -0
- package/templates/nodejs-express/pro/clean/src/infrastructure/providers/PasswordHasher.ts.hbs +14 -0
- package/templates/nodejs-express/pro/clean/src/infrastructure/providers/TokenGenerator.ts.hbs +25 -0
- package/templates/nodejs-express/pro/clean/tsconfig.json.hbs +27 -0
- package/templates/nodejs-express/pro/hexagonal/.env.example.hbs +19 -0
- package/templates/nodejs-express/pro/hexagonal/.github/workflows/ci-cd.yml.hbs +88 -0
- package/templates/nodejs-express/pro/hexagonal/Dockerfile.hbs +45 -0
- package/templates/nodejs-express/pro/hexagonal/README.md.hbs +42 -0
- package/templates/nodejs-express/pro/hexagonal/docker-compose.yml.hbs +18 -0
- package/templates/nodejs-express/pro/hexagonal/infra/main.tf.hbs +83 -0
- package/templates/nodejs-express/pro/hexagonal/infra/modules/ecs/main.tf.hbs +54 -0
- package/templates/nodejs-express/pro/hexagonal/infra/modules/rds/main.tf.hbs +88 -0
- package/templates/nodejs-express/pro/hexagonal/infra/modules/vpc/main.tf.hbs +107 -0
- package/templates/nodejs-express/pro/hexagonal/package.json.hbs +55 -0
- package/templates/nodejs-express/pro/hexagonal/src/adapters/inbound/http/AuthController.ts.hbs +48 -0
- package/templates/nodejs-express/pro/hexagonal/src/adapters/outbound/SecurityAdapters.ts.hbs +31 -0
- package/templates/nodejs-express/pro/hexagonal/src/adapters/outbound/persistence/InMemoryUserAdapter.ts.hbs +38 -0
- package/templates/nodejs-express/pro/hexagonal/src/core/AuthService.ts.hbs +51 -0
- package/templates/nodejs-express/pro/hexagonal/src/core/domain/entities/User.ts.hbs +28 -0
- package/templates/nodejs-express/pro/hexagonal/src/core/ports/inbound/IAuthPort.ts.hbs +11 -0
- package/templates/nodejs-express/pro/hexagonal/src/core/ports/outbound/ISecurityPorts.ts.hbs +15 -0
- package/templates/nodejs-express/pro/hexagonal/src/core/ports/outbound/IUserRepositoryPort.ts.hbs +13 -0
- package/templates/nodejs-express/pro/hexagonal/src/index.ts.hbs +41 -0
- package/templates/nodejs-express/pro/hexagonal/tsconfig.json.hbs +27 -0
- package/templates/nodejs-express/pro/mvc/.env.example.hbs +19 -0
- package/templates/nodejs-express/pro/mvc/.github/workflows/ci-cd.yml.hbs +88 -0
- package/templates/nodejs-express/pro/mvc/Dockerfile.hbs +45 -0
- package/templates/nodejs-express/pro/mvc/README.md.hbs +85 -0
- package/templates/nodejs-express/pro/mvc/docker-compose.yml.hbs +18 -0
- package/templates/nodejs-express/pro/mvc/infra/main.tf.hbs +83 -0
- package/templates/nodejs-express/pro/mvc/infra/modules/ecs/main.tf.hbs +54 -0
- package/templates/nodejs-express/pro/mvc/infra/modules/rds/main.tf.hbs +88 -0
- package/templates/nodejs-express/pro/mvc/infra/modules/vpc/main.tf.hbs +107 -0
- package/templates/nodejs-express/pro/mvc/package.json.hbs +55 -0
- package/templates/nodejs-express/pro/mvc/src/app.ts.hbs +34 -0
- package/templates/nodejs-express/pro/mvc/src/config/database.ts.hbs +10 -0
- package/templates/nodejs-express/pro/mvc/src/controllers/auth.controller.ts.hbs +91 -0
- package/templates/nodejs-express/pro/mvc/src/controllers/healthController.ts.hbs +20 -0
- package/templates/nodejs-express/pro/mvc/src/controllers/payments.controller.ts.hbs +72 -0
- package/templates/nodejs-express/pro/mvc/src/index.ts.hbs +12 -0
- package/templates/nodejs-express/pro/mvc/src/middleware/errorHandler.ts.hbs +22 -0
- package/templates/nodejs-express/pro/mvc/src/middlewares/auth.middleware.ts.hbs +31 -0
- package/templates/nodejs-express/pro/mvc/src/models/.gitkeep +0 -0
- package/templates/nodejs-express/pro/mvc/src/routes/index.ts.hbs +14 -0
- package/templates/nodejs-express/pro/mvc/src/services/.gitkeep +0 -0
- package/templates/nodejs-express/pro/mvc/src/services/stripe.service.ts.hbs +102 -0
- package/templates/nodejs-express/pro/mvc/template.json +18 -0
- package/templates/nodejs-express/pro/mvc/tsconfig.json.hbs +27 -0
- package/templates/python-fastapi/free/mvc/README.md.hbs +41 -0
- package/templates/python-fastapi/free/mvc/app/controllers/health.py.hbs +7 -0
- package/templates/python-fastapi/free/mvc/app/controllers/items.py.hbs +27 -0
- package/templates/python-fastapi/free/mvc/app/main.py.hbs +26 -0
- package/templates/python-fastapi/free/mvc/app/models/item.py.hbs +11 -0
- package/templates/python-fastapi/free/mvc/app/schemas/item.py.hbs +17 -0
- package/templates/python-fastapi/free/mvc/app/services/item_service.py.hbs +33 -0
- package/templates/python-fastapi/free/mvc/requirements.txt.hbs +4 -0
- package/templates/python-fastapi/pro/clean/.env.example.hbs +17 -0
- package/templates/python-fastapi/pro/clean/.github/workflows/ci-cd.yml.hbs +88 -0
- package/templates/python-fastapi/pro/clean/Dockerfile.hbs +20 -0
- package/templates/python-fastapi/pro/clean/app/domain/entities/user.py.hbs +23 -0
- package/templates/python-fastapi/pro/clean/app/domain/repositories/user_repository.py.hbs +22 -0
- package/templates/python-fastapi/pro/clean/app/domain/usecases/register_user.py.hbs +30 -0
- package/templates/python-fastapi/pro/clean/app/infrastructure/database/in_memory_repository.py.hbs +26 -0
- package/templates/python-fastapi/pro/clean/app/infrastructure/http/auth_controller.py.hbs +26 -0
- package/templates/python-fastapi/pro/clean/app/infrastructure/security/adapters.py.hbs +23 -0
- package/templates/python-fastapi/pro/clean/app/main.py.hbs +10 -0
- package/templates/python-fastapi/pro/clean/infra/main.tf.hbs +83 -0
- package/templates/python-fastapi/pro/clean/infra/modules/ecs/main.tf.hbs +54 -0
- package/templates/python-fastapi/pro/clean/infra/modules/rds/main.tf.hbs +88 -0
- package/templates/python-fastapi/pro/clean/infra/modules/vpc/main.tf.hbs +107 -0
- package/templates/python-fastapi/pro/clean/requirements.txt.hbs +12 -0
- package/templates/python-fastapi/pro/hexagonal/.env.example.hbs +17 -0
- package/templates/python-fastapi/pro/hexagonal/.github/workflows/ci-cd.yml.hbs +88 -0
- package/templates/python-fastapi/pro/hexagonal/Dockerfile.hbs +20 -0
- package/templates/python-fastapi/pro/hexagonal/app/adapters/inbound/http_adapter.py.hbs +29 -0
- package/templates/python-fastapi/pro/hexagonal/app/core/domain/user.py.hbs +15 -0
- package/templates/python-fastapi/pro/hexagonal/app/core/ports.py.hbs +25 -0
- package/templates/python-fastapi/pro/hexagonal/app/core/service.py.hbs +28 -0
- package/templates/python-fastapi/pro/hexagonal/app/main.py.hbs +22 -0
- package/templates/python-fastapi/pro/hexagonal/infra/main.tf.hbs +83 -0
- package/templates/python-fastapi/pro/hexagonal/infra/modules/ecs/main.tf.hbs +54 -0
- package/templates/python-fastapi/pro/hexagonal/infra/modules/rds/main.tf.hbs +88 -0
- package/templates/python-fastapi/pro/hexagonal/infra/modules/vpc/main.tf.hbs +107 -0
- package/templates/python-fastapi/pro/hexagonal/requirements.txt.hbs +12 -0
- package/templates/python-fastapi/pro/mvc/.env.example.hbs +17 -0
- package/templates/python-fastapi/pro/mvc/.github/workflows/ci-cd.yml.hbs +88 -0
- package/templates/python-fastapi/pro/mvc/Dockerfile.hbs +20 -0
- package/templates/python-fastapi/pro/mvc/README.md.hbs +41 -0
- package/templates/python-fastapi/pro/mvc/app/controllers/auth.py.hbs +46 -0
- package/templates/python-fastapi/pro/mvc/app/controllers/health.py.hbs +7 -0
- package/templates/python-fastapi/pro/mvc/app/controllers/items.py.hbs +21 -0
- package/templates/python-fastapi/pro/mvc/app/controllers/payments.py.hbs +32 -0
- package/templates/python-fastapi/pro/mvc/app/main.py.hbs +20 -0
- package/templates/python-fastapi/pro/mvc/app/middleware/security.py.hbs +39 -0
- package/templates/python-fastapi/pro/mvc/app/models/item.py.hbs +11 -0
- package/templates/python-fastapi/pro/mvc/app/schemas/item.py.hbs +16 -0
- package/templates/python-fastapi/pro/mvc/app/services/item_service.py.hbs +24 -0
- package/templates/python-fastapi/pro/mvc/infra/main.tf.hbs +83 -0
- package/templates/python-fastapi/pro/mvc/infra/modules/ecs/main.tf.hbs +54 -0
- package/templates/python-fastapi/pro/mvc/infra/modules/rds/main.tf.hbs +88 -0
- package/templates/python-fastapi/pro/mvc/infra/modules/vpc/main.tf.hbs +107 -0
- package/templates/python-fastapi/pro/mvc/requirements.txt.hbs +12 -0
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
# {{projectName}}
|
|
2
|
+
|
|
3
|
+
> Generated by [Kybernus CLI](https://kybernus.dev) 🚀 (Pro - Hexagonal Architecture)
|
|
4
|
+
|
|
5
|
+
## Architecture
|
|
6
|
+
|
|
7
|
+
This project follows **Hexagonal Architecture** (Ports & Adapters):
|
|
8
|
+
|
|
9
|
+
```
|
|
10
|
+
src/
|
|
11
|
+
├── core/ # The Hexagon
|
|
12
|
+
│ ├── domain/ # Business entities
|
|
13
|
+
│ │ └── entities/
|
|
14
|
+
│ ├── ports/ # Interfaces (contracts)
|
|
15
|
+
│ │ ├── inbound/ # What the app CAN DO (use cases)
|
|
16
|
+
│ │ └── outbound/ # What the app NEEDS
|
|
17
|
+
│ └── AuthService.ts # Core business logic
|
|
18
|
+
├── adapters/ # Outside the Hexagon
|
|
19
|
+
│ ├── inbound/ # Driving adapters
|
|
20
|
+
│ │ └── http/ # Express controllers
|
|
21
|
+
│ └── outbound/ # Driven adapters
|
|
22
|
+
│ └── persistence/ # Database implementations
|
|
23
|
+
└── config/ # Application configuration
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
## Key Principles
|
|
27
|
+
|
|
28
|
+
1. **Ports**: Interfaces that define boundaries
|
|
29
|
+
2. **Adapters**: Implementations that connect to external systems
|
|
30
|
+
3. **Dependency Inversion**: Core depends on abstractions, not implementations
|
|
31
|
+
|
|
32
|
+
## Quick Start
|
|
33
|
+
|
|
34
|
+
```bash
|
|
35
|
+
npm install
|
|
36
|
+
cp .env.example .env
|
|
37
|
+
npm run dev
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
---
|
|
41
|
+
|
|
42
|
+
Made with ❤️ using [Kybernus Pro](https://kybernus.dev/pro)
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
version: '3.8'
|
|
2
|
+
|
|
3
|
+
services:
|
|
4
|
+
postgres:
|
|
5
|
+
image: postgres:15-alpine
|
|
6
|
+
container_name: {{kebabCase projectName}}-db
|
|
7
|
+
environment:
|
|
8
|
+
POSTGRES_USER: postgres
|
|
9
|
+
POSTGRES_PASSWORD: postgres
|
|
10
|
+
POSTGRES_DB: {{snakeCase projectName}}
|
|
11
|
+
ports:
|
|
12
|
+
- "5432:5432"
|
|
13
|
+
volumes:
|
|
14
|
+
- postgres_data:/var/lib/postgresql/data
|
|
15
|
+
restart: unless-stopped
|
|
16
|
+
|
|
17
|
+
volumes:
|
|
18
|
+
postgres_data:
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
# Terraform Infrastructure for {{projectName}}
|
|
2
|
+
|
|
3
|
+
terraform {
|
|
4
|
+
required_version = ">= 1.0.0"
|
|
5
|
+
|
|
6
|
+
required_providers {
|
|
7
|
+
aws = {
|
|
8
|
+
source = "hashicorp/aws"
|
|
9
|
+
version = "~> 5.0"
|
|
10
|
+
}
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
# Uncomment for remote state (recommended for production)
|
|
14
|
+
# backend "s3" {
|
|
15
|
+
# bucket = "your-terraform-state-bucket"
|
|
16
|
+
# key = "{{projectNameKebabCase}}/terraform.tfstate"
|
|
17
|
+
# region = "us-east-1"
|
|
18
|
+
# encrypt = true
|
|
19
|
+
# dynamodb_table = "terraform-locks"
|
|
20
|
+
# }
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
provider "aws" {
|
|
24
|
+
region = var.aws_region
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
# Variables
|
|
28
|
+
variable "aws_region" {
|
|
29
|
+
description = "AWS region"
|
|
30
|
+
type = string
|
|
31
|
+
default = "us-east-1"
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
variable "environment" {
|
|
35
|
+
description = "Environment name (dev, staging, prod)"
|
|
36
|
+
type = string
|
|
37
|
+
default = "dev"
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
variable "app_name" {
|
|
41
|
+
description = "Application name"
|
|
42
|
+
type = string
|
|
43
|
+
default = "{{projectNameKebabCase}}"
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
# VPC
|
|
47
|
+
module "vpc" {
|
|
48
|
+
source = "./modules/vpc"
|
|
49
|
+
|
|
50
|
+
app_name = var.app_name
|
|
51
|
+
environment = var.environment
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
# ECS Cluster
|
|
55
|
+
module "ecs" {
|
|
56
|
+
source = "./modules/ecs"
|
|
57
|
+
|
|
58
|
+
app_name = var.app_name
|
|
59
|
+
environment = var.environment
|
|
60
|
+
vpc_id = module.vpc.vpc_id
|
|
61
|
+
subnet_ids = module.vpc.private_subnet_ids
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
# RDS PostgreSQL
|
|
65
|
+
module "rds" {
|
|
66
|
+
source = "./modules/rds"
|
|
67
|
+
|
|
68
|
+
app_name = var.app_name
|
|
69
|
+
environment = var.environment
|
|
70
|
+
vpc_id = module.vpc.vpc_id
|
|
71
|
+
subnet_ids = module.vpc.private_subnet_ids
|
|
72
|
+
security_group_id = module.vpc.db_security_group_id
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
# Outputs
|
|
76
|
+
output "ecs_cluster_name" {
|
|
77
|
+
value = module.ecs.cluster_name
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
output "rds_endpoint" {
|
|
81
|
+
value = module.rds.endpoint
|
|
82
|
+
sensitive = true
|
|
83
|
+
}
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
# ECS Module
|
|
2
|
+
|
|
3
|
+
variable "app_name" {
|
|
4
|
+
type = string
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
variable "environment" {
|
|
8
|
+
type = string
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
variable "vpc_id" {
|
|
12
|
+
type = string
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
variable "subnet_ids" {
|
|
16
|
+
type = list(string)
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
# ECS Cluster
|
|
20
|
+
resource "aws_ecs_cluster" "main" {
|
|
21
|
+
name = "${var.app_name}-${var.environment}"
|
|
22
|
+
|
|
23
|
+
setting {
|
|
24
|
+
name = "containerInsights"
|
|
25
|
+
value = "enabled"
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
tags = {
|
|
29
|
+
Name = "${var.app_name}-${var.environment}"
|
|
30
|
+
Environment = var.environment
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
# ECS Capacity Provider
|
|
35
|
+
resource "aws_ecs_cluster_capacity_providers" "main" {
|
|
36
|
+
cluster_name = aws_ecs_cluster.main.name
|
|
37
|
+
|
|
38
|
+
capacity_providers = ["FARGATE", "FARGATE_SPOT"]
|
|
39
|
+
|
|
40
|
+
default_capacity_provider_strategy {
|
|
41
|
+
base = 1
|
|
42
|
+
weight = 100
|
|
43
|
+
capacity_provider = "FARGATE"
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
# Outputs
|
|
48
|
+
output "cluster_name" {
|
|
49
|
+
value = aws_ecs_cluster.main.name
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
output "cluster_arn" {
|
|
53
|
+
value = aws_ecs_cluster.main.arn
|
|
54
|
+
}
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
# RDS Module
|
|
2
|
+
|
|
3
|
+
variable "app_name" {
|
|
4
|
+
type = string
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
variable "environment" {
|
|
8
|
+
type = string
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
variable "vpc_id" {
|
|
12
|
+
type = string
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
variable "subnet_ids" {
|
|
16
|
+
type = list(string)
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
variable "security_group_id" {
|
|
20
|
+
type = string
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
# DB Subnet Group
|
|
24
|
+
resource "aws_db_subnet_group" "main" {
|
|
25
|
+
name = "${var.app_name}-${var.environment}"
|
|
26
|
+
subnet_ids = var.subnet_ids
|
|
27
|
+
|
|
28
|
+
tags = {
|
|
29
|
+
Name = "${var.app_name}-${var.environment}"
|
|
30
|
+
Environment = var.environment
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
# RDS PostgreSQL Instance
|
|
35
|
+
resource "aws_db_instance" "main" {
|
|
36
|
+
identifier = "${var.app_name}-${var.environment}"
|
|
37
|
+
|
|
38
|
+
engine = "postgres"
|
|
39
|
+
engine_version = "16"
|
|
40
|
+
instance_class = "db.t3.micro"
|
|
41
|
+
|
|
42
|
+
allocated_storage = 20
|
|
43
|
+
max_allocated_storage = 100
|
|
44
|
+
storage_type = "gp3"
|
|
45
|
+
storage_encrypted = true
|
|
46
|
+
|
|
47
|
+
db_name = replace(var.app_name, "-", "_")
|
|
48
|
+
username = "postgres"
|
|
49
|
+
password = random_password.db_password.result
|
|
50
|
+
|
|
51
|
+
db_subnet_group_name = aws_db_subnet_group.main.name
|
|
52
|
+
vpc_security_group_ids = [var.security_group_id]
|
|
53
|
+
|
|
54
|
+
backup_retention_period = 7
|
|
55
|
+
skip_final_snapshot = var.environment != "prod"
|
|
56
|
+
|
|
57
|
+
tags = {
|
|
58
|
+
Name = "${var.app_name}-${var.environment}"
|
|
59
|
+
Environment = var.environment
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
# Random password for DB
|
|
64
|
+
resource "random_password" "db_password" {
|
|
65
|
+
length = 32
|
|
66
|
+
special = false
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
# Store password in SSM
|
|
70
|
+
resource "aws_ssm_parameter" "db_password" {
|
|
71
|
+
name = "/${var.app_name}/${var.environment}/db-password"
|
|
72
|
+
description = "Database password for ${var.app_name}"
|
|
73
|
+
type = "SecureString"
|
|
74
|
+
value = random_password.db_password.result
|
|
75
|
+
|
|
76
|
+
tags = {
|
|
77
|
+
Environment = var.environment
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
# Outputs
|
|
82
|
+
output "endpoint" {
|
|
83
|
+
value = aws_db_instance.main.endpoint
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
output "db_name" {
|
|
87
|
+
value = aws_db_instance.main.db_name
|
|
88
|
+
}
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
# VPC Module
|
|
2
|
+
|
|
3
|
+
variable "app_name" {
|
|
4
|
+
type = string
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
variable "environment" {
|
|
8
|
+
type = string
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
# VPC
|
|
12
|
+
resource "aws_vpc" "main" {
|
|
13
|
+
cidr_block = "10.0.0.0/16"
|
|
14
|
+
enable_dns_hostnames = true
|
|
15
|
+
enable_dns_support = true
|
|
16
|
+
|
|
17
|
+
tags = {
|
|
18
|
+
Name = "${var.app_name}-${var.environment}-vpc"
|
|
19
|
+
Environment = var.environment
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
# Public Subnets
|
|
24
|
+
resource "aws_subnet" "public" {
|
|
25
|
+
count = 2
|
|
26
|
+
vpc_id = aws_vpc.main.id
|
|
27
|
+
cidr_block = "10.0.${count.index + 1}.0/24"
|
|
28
|
+
availability_zone = data.aws_availability_zones.available.names[count.index]
|
|
29
|
+
|
|
30
|
+
map_public_ip_on_launch = true
|
|
31
|
+
|
|
32
|
+
tags = {
|
|
33
|
+
Name = "${var.app_name}-${var.environment}-public-${count.index + 1}"
|
|
34
|
+
Environment = var.environment
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
# Private Subnets
|
|
39
|
+
resource "aws_subnet" "private" {
|
|
40
|
+
count = 2
|
|
41
|
+
vpc_id = aws_vpc.main.id
|
|
42
|
+
cidr_block = "10.0.${count.index + 10}.0/24"
|
|
43
|
+
availability_zone = data.aws_availability_zones.available.names[count.index]
|
|
44
|
+
|
|
45
|
+
tags = {
|
|
46
|
+
Name = "${var.app_name}-${var.environment}-private-${count.index + 1}"
|
|
47
|
+
Environment = var.environment
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
# Internet Gateway
|
|
52
|
+
resource "aws_internet_gateway" "main" {
|
|
53
|
+
vpc_id = aws_vpc.main.id
|
|
54
|
+
|
|
55
|
+
tags = {
|
|
56
|
+
Name = "${var.app_name}-${var.environment}-igw"
|
|
57
|
+
Environment = var.environment
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
# Data source for AZs
|
|
62
|
+
data "aws_availability_zones" "available" {
|
|
63
|
+
state = "available"
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
# Security Group for DB
|
|
67
|
+
resource "aws_security_group" "db" {
|
|
68
|
+
name = "${var.app_name}-${var.environment}-db-sg"
|
|
69
|
+
description = "Security group for database"
|
|
70
|
+
vpc_id = aws_vpc.main.id
|
|
71
|
+
|
|
72
|
+
ingress {
|
|
73
|
+
from_port = 5432
|
|
74
|
+
to_port = 5432
|
|
75
|
+
protocol = "tcp"
|
|
76
|
+
cidr_blocks = ["10.0.0.0/16"]
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
egress {
|
|
80
|
+
from_port = 0
|
|
81
|
+
to_port = 0
|
|
82
|
+
protocol = "-1"
|
|
83
|
+
cidr_blocks = ["0.0.0.0/0"]
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
tags = {
|
|
87
|
+
Name = "${var.app_name}-${var.environment}-db-sg"
|
|
88
|
+
Environment = var.environment
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
# Outputs
|
|
93
|
+
output "vpc_id" {
|
|
94
|
+
value = aws_vpc.main.id
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
output "public_subnet_ids" {
|
|
98
|
+
value = aws_subnet.public[*].id
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
output "private_subnet_ids" {
|
|
102
|
+
value = aws_subnet.private[*].id
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
output "db_security_group_id" {
|
|
106
|
+
value = aws_security_group.db.id
|
|
107
|
+
}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "{{kebabCase projectName}}",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "Generated by Kybernus CLI (Pro)",
|
|
5
|
+
"main": "dist/index.js",
|
|
6
|
+
"scripts": {
|
|
7
|
+
"dev": "tsx watch src/index.ts",
|
|
8
|
+
"build": "rimraf dist && tsc",
|
|
9
|
+
"start": "node dist/index.js",
|
|
10
|
+
"lint": "eslint src --ext .ts",
|
|
11
|
+
"format": "prettier --write \"src/**/*.ts\"",
|
|
12
|
+
"test": "jest"
|
|
13
|
+
},
|
|
14
|
+
"keywords": [
|
|
15
|
+
"express",
|
|
16
|
+
"api",
|
|
17
|
+
"typescript",
|
|
18
|
+
"mvc",
|
|
19
|
+
"saas",
|
|
20
|
+
"stripe",
|
|
21
|
+
"auth"
|
|
22
|
+
],
|
|
23
|
+
"author": "",
|
|
24
|
+
"license": "MIT",
|
|
25
|
+
"dependencies": {
|
|
26
|
+
"express": "^4.18.2",
|
|
27
|
+
"dotenv": "^16.4.5",
|
|
28
|
+
"cors": "^2.8.5",
|
|
29
|
+
"helmet": "^7.1.0",
|
|
30
|
+
"morgan": "^1.10.0",
|
|
31
|
+
"jsonwebtoken": "^9.0.2",
|
|
32
|
+
"bcryptjs": "^2.4.3",
|
|
33
|
+
"stripe": "^14.14.0"
|
|
34
|
+
},
|
|
35
|
+
"devDependencies": {
|
|
36
|
+
"@types/express": "^4.17.21",
|
|
37
|
+
"@types/node": "^20.11.19",
|
|
38
|
+
"@types/cors": "^2.8.17",
|
|
39
|
+
"@types/morgan": "^1.9.9",
|
|
40
|
+
"@types/jsonwebtoken": "^9.0.5",
|
|
41
|
+
"@types/bcryptjs": "^2.4.6",
|
|
42
|
+
"typescript": "^5.3.3",
|
|
43
|
+
"tsx": "^4.7.1",
|
|
44
|
+
"rimraf": "^5.0.5",
|
|
45
|
+
"eslint": "^8.56.0",
|
|
46
|
+
"@typescript-eslint/eslint-plugin": "^6.21.0",
|
|
47
|
+
"@typescript-eslint/parser": "^6.21.0",
|
|
48
|
+
"prettier": "^3.2.5",
|
|
49
|
+
"jest": "^29.7.0",
|
|
50
|
+
"@types/jest": "^29.5.12"
|
|
51
|
+
},
|
|
52
|
+
"engines": {
|
|
53
|
+
"node": ">=18.0.0"
|
|
54
|
+
}
|
|
55
|
+
}
|
package/templates/nodejs-express/pro/hexagonal/src/adapters/inbound/http/AuthController.ts.hbs
ADDED
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import { Router, Request, Response } from 'express';
|
|
2
|
+
import { IAuthPort } from '../../../core/ports/inbound/IAuthPort';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* HTTP Auth Controller - Inbound Adapter
|
|
6
|
+
* Adapts HTTP requests to the application port
|
|
7
|
+
*/
|
|
8
|
+
export function createAuthController(authService: IAuthPort): Router {
|
|
9
|
+
const router = Router();
|
|
10
|
+
|
|
11
|
+
router.post('/register', async (req: Request, res: Response) => {
|
|
12
|
+
try {
|
|
13
|
+
const { email, name, password } = req.body;
|
|
14
|
+
const result = await authService.register(email, name, password);
|
|
15
|
+
res.status(201).json({
|
|
16
|
+
token: result.token,
|
|
17
|
+
user: { id: result.user.id, email: result.user.email, name: result.user.name },
|
|
18
|
+
});
|
|
19
|
+
} catch (error: any) {
|
|
20
|
+
res.status(400).json({ error: error.message });
|
|
21
|
+
}
|
|
22
|
+
});
|
|
23
|
+
|
|
24
|
+
router.post('/login', async (req: Request, res: Response) => {
|
|
25
|
+
try {
|
|
26
|
+
const { email, password } = req.body;
|
|
27
|
+
const result = await authService.login(email, password);
|
|
28
|
+
res.json({
|
|
29
|
+
token: result.token,
|
|
30
|
+
user: { id: result.user.id, email: result.user.email, name: result.user.name },
|
|
31
|
+
});
|
|
32
|
+
} catch (error: any) {
|
|
33
|
+
res.status(401).json({ error: error.message });
|
|
34
|
+
}
|
|
35
|
+
});
|
|
36
|
+
|
|
37
|
+
router.get('/me', async (req: Request, res: Response) => {
|
|
38
|
+
const token = req.headers.authorization?.split(' ')[1];
|
|
39
|
+
if (!token) return res.status(401).json({ error: 'No token' });
|
|
40
|
+
|
|
41
|
+
const user = await authService.validateToken(token);
|
|
42
|
+
if (!user) return res.status(401).json({ error: 'Invalid token' });
|
|
43
|
+
|
|
44
|
+
res.json({ user: { id: user.id, email: user.email, name: user.name } });
|
|
45
|
+
});
|
|
46
|
+
|
|
47
|
+
return router;
|
|
48
|
+
}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import bcrypt from 'bcryptjs';
|
|
2
|
+
import jwt from 'jsonwebtoken';
|
|
3
|
+
import { IPasswordHasherPort, ITokenGeneratorPort } from '../../../core/ports/outbound/ISecurityPorts';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Bcrypt Password Hasher Adapter
|
|
7
|
+
*/
|
|
8
|
+
export const bcryptAdapter: IPasswordHasherPort = {
|
|
9
|
+
async hash(password: string): Promise<string> {
|
|
10
|
+
return bcrypt.hash(password, 10);
|
|
11
|
+
},
|
|
12
|
+
async compare(password: string, hash: string): Promise<boolean> {
|
|
13
|
+
return bcrypt.compare(password, hash);
|
|
14
|
+
},
|
|
15
|
+
};
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* JWT Token Generator Adapter
|
|
19
|
+
*/
|
|
20
|
+
export const jwtAdapter: ITokenGeneratorPort = {
|
|
21
|
+
generate(userId: string, email: string): string {
|
|
22
|
+
return jwt.sign({ id: userId, email }, process.env.JWT_SECRET || 'secret', { expiresIn: '7d' });
|
|
23
|
+
},
|
|
24
|
+
verify(token: string): { id: string; email: string } | null {
|
|
25
|
+
try {
|
|
26
|
+
return jwt.verify(token, process.env.JWT_SECRET || 'secret') as { id: string; email: string };
|
|
27
|
+
} catch {
|
|
28
|
+
return null;
|
|
29
|
+
}
|
|
30
|
+
},
|
|
31
|
+
};
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { User } from '../../core/domain/entities/User';
|
|
2
|
+
import { IUserRepositoryPort } from '../../core/ports/outbound/IUserRepositoryPort';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* In-Memory User Repository Adapter
|
|
6
|
+
* Implements the outbound port
|
|
7
|
+
*/
|
|
8
|
+
export class InMemoryUserAdapter implements IUserRepositoryPort {
|
|
9
|
+
private users: Map<string, User> = new Map();
|
|
10
|
+
|
|
11
|
+
async findById(id: string): Promise<User | null> {
|
|
12
|
+
return this.users.get(id) || null;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
async findByEmail(email: string): Promise<User | null> {
|
|
16
|
+
for (const user of this.users.values()) {
|
|
17
|
+
if (user.email === email) return user;
|
|
18
|
+
}
|
|
19
|
+
return null;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
async save(user: User): Promise<User> {
|
|
23
|
+
const id = Date.now().toString();
|
|
24
|
+
const savedUser = user.withId(id);
|
|
25
|
+
this.users.set(id, savedUser);
|
|
26
|
+
return savedUser;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
async update(user: User): Promise<User> {
|
|
30
|
+
if (!user.id) throw new Error('User must have an ID');
|
|
31
|
+
this.users.set(user.id, user);
|
|
32
|
+
return user;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
async delete(id: string): Promise<void> {
|
|
36
|
+
this.users.delete(id);
|
|
37
|
+
}
|
|
38
|
+
}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import { User } from '../domain/entities/User';
|
|
2
|
+
import { IAuthPort } from '../ports/inbound/IAuthPort';
|
|
3
|
+
import { IUserRepositoryPort } from '../ports/outbound/IUserRepositoryPort';
|
|
4
|
+
import { IPasswordHasherPort, ITokenGeneratorPort } from '../ports/outbound/ISecurityPorts';
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Auth Service - Application Core
|
|
8
|
+
* Implements the inbound port using outbound ports
|
|
9
|
+
*/
|
|
10
|
+
export class AuthService implements IAuthPort {
|
|
11
|
+
constructor(
|
|
12
|
+
private readonly userRepository: IUserRepositoryPort,
|
|
13
|
+
private readonly passwordHasher: IPasswordHasherPort,
|
|
14
|
+
private readonly tokenGenerator: ITokenGeneratorPort
|
|
15
|
+
) {}
|
|
16
|
+
|
|
17
|
+
async register(email: string, name: string, password: string): Promise<{ user: User; token: string }> {
|
|
18
|
+
const existingUser = await this.userRepository.findByEmail(email);
|
|
19
|
+
if (existingUser) {
|
|
20
|
+
throw new Error('User already exists');
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
const hashedPassword = await this.passwordHasher.hash(password);
|
|
24
|
+
const user = new User(undefined, email, name, hashedPassword);
|
|
25
|
+
const savedUser = await this.userRepository.save(user);
|
|
26
|
+
const token = this.tokenGenerator.generate(savedUser.id!, savedUser.email);
|
|
27
|
+
|
|
28
|
+
return { user: savedUser, token };
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
async login(email: string, password: string): Promise<{ user: User; token: string }> {
|
|
32
|
+
const user = await this.userRepository.findByEmail(email);
|
|
33
|
+
if (!user) {
|
|
34
|
+
throw new Error('Invalid credentials');
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
const isValid = await this.passwordHasher.compare(password, user.password);
|
|
38
|
+
if (!isValid) {
|
|
39
|
+
throw new Error('Invalid credentials');
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
const token = this.tokenGenerator.generate(user.id!, user.email);
|
|
43
|
+
return { user, token };
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
async validateToken(token: string): Promise<User | null> {
|
|
47
|
+
const decoded = this.tokenGenerator.verify(token);
|
|
48
|
+
if (!decoded) return null;
|
|
49
|
+
return this.userRepository.findById(decoded.id);
|
|
50
|
+
}
|
|
51
|
+
}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* User Entity - Core Domain
|
|
3
|
+
* Hexagonal Architecture: This is the heart of the hexagon
|
|
4
|
+
*/
|
|
5
|
+
export class User {
|
|
6
|
+
constructor(
|
|
7
|
+
public readonly id: string | undefined,
|
|
8
|
+
public readonly email: string,
|
|
9
|
+
public readonly name: string,
|
|
10
|
+
public readonly password: string,
|
|
11
|
+
public readonly stripeCustomerId?: string,
|
|
12
|
+
public readonly createdAt: Date = new Date()
|
|
13
|
+
) {
|
|
14
|
+
this.validateEmail(email);
|
|
15
|
+
this.validatePassword(password);
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
private validateEmail(email: string): void {
|
|
19
|
+
if (!email || !email.includes('@')) {
|
|
20
|
+
throw new Error('Invalid email format');
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
private validatePassword(password: string): void {
|
|
25
|
+
if (!password || password.length < 8) { throw new Error('Password must be at least 8 characters'); } } withId(id:
|
|
26
|
+
string): User { return new User(id, this.email, this.name, this.password, this.stripeCustomerId, this.createdAt); }
|
|
27
|
+
withStripeCustomerId(customerId: string): User { return new User(this.id, this.email, this.name, this.password,
|
|
28
|
+
customerId, this.createdAt); } }
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { User } from '../../domain/entities/User';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Auth Port - Inbound (Driving) Port
|
|
5
|
+
* Defines what the application CAN DO (use cases)
|
|
6
|
+
*/
|
|
7
|
+
export interface IAuthPort {
|
|
8
|
+
register(email: string, name: string, password: string): Promise<{ user: User; token: string }>;
|
|
9
|
+
login(email: string, password: string): Promise<{ user: User; token: string }>;
|
|
10
|
+
validateToken(token: string): Promise<User | null>;
|
|
11
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Password Hasher Port - Outbound Port
|
|
3
|
+
*/
|
|
4
|
+
export interface IPasswordHasherPort {
|
|
5
|
+
hash(password: string): Promise<string>;
|
|
6
|
+
compare(password: string, hash: string): Promise<boolean>;
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* Token Generator Port - Outbound Port
|
|
11
|
+
*/
|
|
12
|
+
export interface ITokenGeneratorPort {
|
|
13
|
+
generate(userId: string, email: string): string;
|
|
14
|
+
verify(token: string): { id: string; email: string } | null;
|
|
15
|
+
}
|
package/templates/nodejs-express/pro/hexagonal/src/core/ports/outbound/IUserRepositoryPort.ts.hbs
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { User } from '../../domain/entities/User';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* User Repository Port - Outbound (Driven) Port
|
|
5
|
+
* Defines what the application NEEDS from the outside world
|
|
6
|
+
*/
|
|
7
|
+
export interface IUserRepositoryPort {
|
|
8
|
+
findById(id: string): Promise<User | null>;
|
|
9
|
+
findByEmail(email: string): Promise<User | null>;
|
|
10
|
+
save(user: User): Promise<User>;
|
|
11
|
+
update(user: User): Promise<User>;
|
|
12
|
+
delete(id: string): Promise<void>;
|
|
13
|
+
}
|