spoonfeeder 0.1.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/LICENSE +21 -0
- package/README.md +249 -0
- package/dist/generator/ai-context-assembler.d.ts +4 -0
- package/dist/generator/ai-context-assembler.js +52 -0
- package/dist/generator/ai-context-assembler.js.map +1 -0
- package/dist/generator/env-merger.d.ts +3 -0
- package/dist/generator/env-merger.js +16 -0
- package/dist/generator/env-merger.js.map +1 -0
- package/dist/generator/generator.d.ts +3 -0
- package/dist/generator/generator.js +253 -0
- package/dist/generator/generator.js.map +1 -0
- package/dist/generator/package-json-merger.d.ts +6 -0
- package/dist/generator/package-json-merger.js +29 -0
- package/dist/generator/package-json-merger.js.map +1 -0
- package/dist/generator/post-generate.d.ts +1 -0
- package/dist/generator/post-generate.js +28 -0
- package/dist/generator/post-generate.js.map +1 -0
- package/dist/generator/template-engine.d.ts +4 -0
- package/dist/generator/template-engine.js +20 -0
- package/dist/generator/template-engine.js.map +1 -0
- package/dist/generators/add-recipe/generator.d.ts +3 -0
- package/dist/generators/add-recipe/generator.js +153 -0
- package/dist/generators/add-recipe/generator.js.map +1 -0
- package/dist/generators/list-recipes/generator.d.ts +3 -0
- package/dist/generators/list-recipes/generator.js +58 -0
- package/dist/generators/list-recipes/generator.js.map +1 -0
- package/dist/generators/migrate-recipe/generator.d.ts +9 -0
- package/dist/generators/migrate-recipe/generator.js +90 -0
- package/dist/generators/migrate-recipe/generator.js.map +1 -0
- package/dist/generators/migrate-recipe/migration-guidance.d.ts +1 -0
- package/dist/generators/migrate-recipe/migration-guidance.js +159 -0
- package/dist/generators/migrate-recipe/migration-guidance.js.map +1 -0
- package/dist/generators/remove-recipe/generator.d.ts +3 -0
- package/dist/generators/remove-recipe/generator.js +176 -0
- package/dist/generators/remove-recipe/generator.js.map +1 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +40 -0
- package/dist/index.js.map +1 -0
- package/dist/prompts/add-ons.d.ts +3 -0
- package/dist/prompts/add-ons.js +29 -0
- package/dist/prompts/add-ons.js.map +1 -0
- package/dist/prompts/ci-cd.d.ts +2 -0
- package/dist/prompts/ci-cd.js +19 -0
- package/dist/prompts/ci-cd.js.map +1 -0
- package/dist/prompts/cloud-provider.d.ts +2 -0
- package/dist/prompts/cloud-provider.js +18 -0
- package/dist/prompts/cloud-provider.js.map +1 -0
- package/dist/prompts/confirmation.d.ts +2 -0
- package/dist/prompts/confirmation.js +29 -0
- package/dist/prompts/confirmation.js.map +1 -0
- package/dist/prompts/deployment.d.ts +2 -0
- package/dist/prompts/deployment.js +20 -0
- package/dist/prompts/deployment.js.map +1 -0
- package/dist/prompts/frontend.d.ts +2 -0
- package/dist/prompts/frontend.js +18 -0
- package/dist/prompts/frontend.js.map +1 -0
- package/dist/prompts/project-name.d.ts +5 -0
- package/dist/prompts/project-name.js +34 -0
- package/dist/prompts/project-name.js.map +1 -0
- package/dist/prompts/project-type.d.ts +2 -0
- package/dist/prompts/project-type.js +22 -0
- package/dist/prompts/project-type.js.map +1 -0
- package/dist/prompts/run-all.d.ts +3 -0
- package/dist/prompts/run-all.js +83 -0
- package/dist/prompts/run-all.js.map +1 -0
- package/dist/prompts/transport.d.ts +2 -0
- package/dist/prompts/transport.js +22 -0
- package/dist/prompts/transport.js.map +1 -0
- package/dist/recipes/definitions.d.ts +2 -0
- package/dist/recipes/definitions.js +3647 -0
- package/dist/recipes/definitions.js.map +1 -0
- package/dist/recipes/recipe.interface.d.ts +8 -0
- package/dist/recipes/recipe.interface.js +2 -0
- package/dist/recipes/recipe.interface.js.map +1 -0
- package/dist/recipes/registry.d.ts +9 -0
- package/dist/recipes/registry.js +23 -0
- package/dist/recipes/registry.js.map +1 -0
- package/dist/types.d.ts +70 -0
- package/dist/types.js +152 -0
- package/dist/types.js.map +1 -0
- package/dist/utils/ai-context-updater.d.ts +6 -0
- package/dist/utils/ai-context-updater.js +50 -0
- package/dist/utils/ai-context-updater.js.map +1 -0
- package/dist/utils/dependency-checker.d.ts +14 -0
- package/dist/utils/dependency-checker.js +27 -0
- package/dist/utils/dependency-checker.js.map +1 -0
- package/dist/utils/env-updater.d.ts +7 -0
- package/dist/utils/env-updater.js +35 -0
- package/dist/utils/env-updater.js.map +1 -0
- package/dist/utils/main-ts-updater.d.ts +37 -0
- package/dist/utils/main-ts-updater.js +144 -0
- package/dist/utils/main-ts-updater.js.map +1 -0
- package/dist/utils/module-updater.d.ts +26 -0
- package/dist/utils/module-updater.js +167 -0
- package/dist/utils/module-updater.js.map +1 -0
- package/dist/utils/recipe-manifest.d.ts +24 -0
- package/dist/utils/recipe-manifest.js +45 -0
- package/dist/utils/recipe-manifest.js.map +1 -0
- package/dist/validation/config-validator.d.ts +13 -0
- package/dist/validation/config-validator.js +50 -0
- package/dist/validation/config-validator.js.map +1 -0
- package/dist/validation/conflict-detector.d.ts +7 -0
- package/dist/validation/conflict-detector.js +37 -0
- package/dist/validation/conflict-detector.js.map +1 -0
- package/generators.json +24 -0
- package/package.json +78 -0
- package/src/generators/add-recipe/schema.json +21 -0
- package/src/generators/list-recipes/schema.json +18 -0
- package/src/generators/migrate-recipe/schema.json +20 -0
- package/src/generators/remove-recipe/schema.json +21 -0
- package/templates/base/.env.example.ejs +3 -0
- package/templates/base/README.md.ejs +20 -0
- package/templates/base/SECURITY.md +36 -0
- package/templates/base/commitlint.config.js +15 -0
- package/templates/base/docs/adr/000-template.md +45 -0
- package/templates/base/docs/adr/001-framework-selection.md +54 -0
- package/templates/base/docs/adr/002-error-handling-strategy.md +36 -0
- package/templates/base/docs/adr/003-database-strategy.md +40 -0
- package/templates/base/docs/adr/004-authentication-architecture.md +44 -0
- package/templates/base/docs/adr/005-deployment-strategy.md +40 -0
- package/templates/base/docs/adr/006-testing-strategy.md +41 -0
- package/templates/base/docs/adr/007-scaffolder-architecture.md +64 -0
- package/templates/base/docs/adr/008-recipe-system.md +47 -0
- package/templates/base/docs/adr/009-standards-compliance.md +54 -0
- package/templates/base/docs/adr/010-ai-context-generation.md +44 -0
- package/templates/base/docs/adr/011-package-versioning.md +44 -0
- package/templates/base/docs/adr/012-monorepo-strategy.md +54 -0
- package/templates/base/docs/adr/013-http-adapter.md +63 -0
- package/templates/base/docs/adr/014-build-toolchain.md +61 -0
- package/templates/base/docs/adr/015-cloud-provider-strategy.md +49 -0
- package/templates/base/docs/adr/016-ci-cd-pipeline-strategy.md +52 -0
- package/templates/base/docs/adr/017-logging-strategy.md +63 -0
- package/templates/base/docs/adr/018-security-architecture.md +61 -0
- package/templates/base/docs/adr/019-project-type-design.md +61 -0
- package/templates/base/docs/adr/020-frontend-framework-support.md +57 -0
- package/templates/base/docs/adr/021-observability-strategy.md +68 -0
- package/templates/base/docs/adr/022-api-design-patterns.md +64 -0
- package/templates/base/docs/adr/023-error-hierarchy.md +54 -0
- package/templates/base/docs/adr/024-request-context-pattern.md +57 -0
- package/templates/base/docs/adr/025-data-patterns.md +58 -0
- package/templates/base/docs/adr/026-migration-strategy.md +57 -0
- package/templates/base/docs/adr/027-dependency-management.md +60 -0
- package/templates/base/docs/adr/028-code-quality-toolchain.md +60 -0
- package/templates/base/docs/adr/029-admin-panel.md +53 -0
- package/templates/base/docs/adr/030-performance-patterns.md +60 -0
- package/templates/base/docs/adr/031-nx-generators-roadmap.md +73 -0
- package/templates/base/docs/runbooks/000-template.md +78 -0
- package/templates/base/docs/sla-slo.md +36 -0
- package/templates/base/dot-editorconfig +12 -0
- package/templates/base/dot-github/ISSUE_TEMPLATE/bug_report.md +33 -0
- package/templates/base/dot-github/ISSUE_TEMPLATE/feature_request.md +21 -0
- package/templates/base/dot-github/pull_request_template.md +32 -0
- package/templates/base/dot-gitignore +28 -0
- package/templates/base/dot-husky/commit-msg +1 -0
- package/templates/base/dot-husky/pre-commit +1 -0
- package/templates/base/dot-husky/pre-push +2 -0
- package/templates/base/dot-npmrc +1 -0
- package/templates/base/dot-nvmrc +1 -0
- package/templates/base/dot-prettierrc +8 -0
- package/templates/base/eslint.config.mjs +35 -0
- package/templates/base/jest.config.ts +56 -0
- package/templates/base/nest-cli.json.ejs +10 -0
- package/templates/base/nx.json +3 -0
- package/templates/base/package.json.ejs +78 -0
- package/templates/base/src/app/modules/.gitkeep +0 -0
- package/templates/base/src/config/.gitkeep +0 -0
- package/templates/base/src/infrastructure/database/entities/.gitkeep +0 -0
- package/templates/base/src/infrastructure/database/migrations/.gitkeep +0 -0
- package/templates/base/src/infrastructure/database/repositories/.gitkeep +0 -0
- package/templates/base/src/infrastructure/http/.gitkeep +0 -0
- package/templates/base/src/infrastructure/notifications/.gitkeep +0 -0
- package/templates/base/src/infrastructure/queue/.gitkeep +0 -0
- package/templates/base/src/infrastructure/storage/.gitkeep +0 -0
- package/templates/base/src/shared/constants/error-codes.constant.ts +30 -0
- package/templates/base/src/shared/constants/http.constant.ts +134 -0
- package/templates/base/src/shared/constants/index.ts +2 -0
- package/templates/base/src/shared/decorators/.gitkeep +0 -0
- package/templates/base/src/shared/decorators/api-paginated-response.decorator.ts +10 -0
- package/templates/base/src/shared/errors/application.error.ts +21 -0
- package/templates/base/src/shared/errors/forbidden.error.ts +7 -0
- package/templates/base/src/shared/errors/index.ts +6 -0
- package/templates/base/src/shared/errors/invalid-request.error.ts +7 -0
- package/templates/base/src/shared/errors/not-found.error.ts +7 -0
- package/templates/base/src/shared/errors/requester.error.ts +7 -0
- package/templates/base/src/shared/errors/validation.error.ts +7 -0
- package/templates/base/src/shared/filters/http-exception.filter.ts +139 -0
- package/templates/base/src/shared/guards/.gitkeep +0 -0
- package/templates/base/src/shared/interceptors/interfaces/.gitkeep +0 -0
- package/templates/base/src/shared/interceptors/response.interceptor.ts +22 -0
- package/templates/base/src/shared/middleware/request-timeout.middleware.ts +32 -0
- package/templates/base/src/shared/pipes/parse-uuid.pipe.ts +13 -0
- package/templates/base/src/shared/utils/index.ts +2 -0
- package/templates/base/src/shared/utils/retry.util.ts +32 -0
- package/templates/base/src/shared/utils/sleep.util.ts +3 -0
- package/templates/base/tests/e2e/app.e2e-spec.ts.ejs +25 -0
- package/templates/base/tests/factories/.gitkeep +0 -0
- package/templates/base/tests/helpers/.gitkeep +0 -0
- package/templates/base/tests/integration/.gitkeep +0 -0
- package/templates/base/tests/unit/app.module.spec.ts +11 -0
- package/templates/base/tests/unit/shared/errors/error-hierarchy.spec.ts +69 -0
- package/templates/base/tests/unit/shared/filters/http-exception.filter.spec.ts +188 -0
- package/templates/base/tests/unit/shared/interceptors/response.interceptor.spec.ts +54 -0
- package/templates/base/tests/unit/shared/pipes/parse-uuid.pipe.spec.ts +14 -0
- package/templates/base/tsconfig.build.json +4 -0
- package/templates/base/tsconfig.json.ejs +26 -0
- package/templates/project-types/aws-lambda/package-fragment.json +8 -0
- package/templates/project-types/aws-lambda/src/app.module.ts.ejs +9 -0
- package/templates/project-types/aws-lambda/src/main.ts.ejs +32 -0
- package/templates/project-types/aws-lambda/tests/unit/handler.spec.ts +7 -0
- package/templates/project-types/cli-app/package-fragment.json +8 -0
- package/templates/project-types/cli-app/src/app.module.ts.ejs +11 -0
- package/templates/project-types/cli-app/src/commands/hello.command.ts.ejs +8 -0
- package/templates/project-types/cli-app/src/main.ts.ejs +8 -0
- package/templates/project-types/cli-app/tests/unit/commands/hello.command.spec.ts +17 -0
- package/templates/project-types/full-stack/apps/api/src/app.module.ts.ejs +9 -0
- package/templates/project-types/full-stack/apps/api/src/main.ts.ejs +32 -0
- package/templates/project-types/full-stack/frontend/nextjs/.cursor/rules/nextjs.mdc +12 -0
- package/templates/project-types/full-stack/frontend/nextjs/.github/copilot-instructions.md +23 -0
- package/templates/project-types/full-stack/frontend/nextjs/CLAUDE.md +25 -0
- package/templates/project-types/full-stack/frontend/nextjs/next.config.ts +9 -0
- package/templates/project-types/full-stack/frontend/nextjs/package.json +21 -0
- package/templates/project-types/full-stack/frontend/nextjs/src/app/layout.tsx +9 -0
- package/templates/project-types/full-stack/frontend/nextjs/src/app/page.tsx +8 -0
- package/templates/project-types/full-stack/frontend/nextjs/tsconfig.json +21 -0
- package/templates/project-types/full-stack/frontend/nuxt/.cursor/rules/nuxt.mdc +14 -0
- package/templates/project-types/full-stack/frontend/nuxt/.github/copilot-instructions.md +25 -0
- package/templates/project-types/full-stack/frontend/nuxt/CLAUDE.md +25 -0
- package/templates/project-types/full-stack/frontend/nuxt/app.vue +5 -0
- package/templates/project-types/full-stack/frontend/nuxt/nuxt.config.ts +6 -0
- package/templates/project-types/full-stack/frontend/nuxt/package.json +17 -0
- package/templates/project-types/full-stack/frontend/nuxt/pages/index.vue +3 -0
- package/templates/project-types/full-stack/frontend/nuxt/tsconfig.json +1 -0
- package/templates/project-types/full-stack/frontend/sveltekit/.cursor/rules/sveltekit.mdc +13 -0
- package/templates/project-types/full-stack/frontend/sveltekit/.github/copilot-instructions.md +24 -0
- package/templates/project-types/full-stack/frontend/sveltekit/CLAUDE.md +25 -0
- package/templates/project-types/full-stack/frontend/sveltekit/package.json +17 -0
- package/templates/project-types/full-stack/frontend/sveltekit/src/app.html +5 -0
- package/templates/project-types/full-stack/frontend/sveltekit/src/routes/+page.svelte +1 -0
- package/templates/project-types/full-stack/frontend/sveltekit/svelte.config.js +5 -0
- package/templates/project-types/full-stack/frontend/sveltekit/vite.config.ts +9 -0
- package/templates/project-types/full-stack/frontend/vite-react/.cursor/rules/react.mdc +12 -0
- package/templates/project-types/full-stack/frontend/vite-react/.github/copilot-instructions.md +23 -0
- package/templates/project-types/full-stack/frontend/vite-react/CLAUDE.md +24 -0
- package/templates/project-types/full-stack/frontend/vite-react/index.html +5 -0
- package/templates/project-types/full-stack/frontend/vite-react/package.json +22 -0
- package/templates/project-types/full-stack/frontend/vite-react/src/App.tsx +8 -0
- package/templates/project-types/full-stack/frontend/vite-react/src/main.tsx +9 -0
- package/templates/project-types/full-stack/frontend/vite-react/tsconfig.json +21 -0
- package/templates/project-types/full-stack/frontend/vite-react/vite.config.ts +9 -0
- package/templates/project-types/full-stack/libs/shared-types/package.json.ejs +6 -0
- package/templates/project-types/full-stack/libs/shared-types/src/index.ts.ejs +15 -0
- package/templates/project-types/full-stack/nx.json.ejs +20 -0
- package/templates/project-types/full-stack/package-fragment.json +14 -0
- package/templates/project-types/full-stack/pnpm-workspace.yaml +3 -0
- package/templates/project-types/full-stack/tsconfig.json.ejs +27 -0
- package/templates/project-types/http-api/src/app.module.ts.ejs +9 -0
- package/templates/project-types/http-api/src/main.ts.ejs +30 -0
- package/templates/project-types/http-api/tests/e2e/health.e2e-spec.ts +23 -0
- package/templates/project-types/microservice/package-fragment.json +5 -0
- package/templates/project-types/microservice/src/app.module.ts.ejs +9 -0
- package/templates/project-types/microservice/src/main.ts.ejs +15 -0
- package/templates/project-types/microservice/tests/unit/app.module.spec.ts +9 -0
- package/templates/project-types/monorepo/README.md.ejs +33 -0
- package/templates/project-types/monorepo/apps/api/src/app.module.ts.ejs +9 -0
- package/templates/project-types/monorepo/apps/api/src/main.ts.ejs +30 -0
- package/templates/project-types/monorepo/libs/common/package.json.ejs +6 -0
- package/templates/project-types/monorepo/libs/common/src/index.ts.ejs +17 -0
- package/templates/project-types/monorepo/nx.json.ejs +20 -0
- package/templates/project-types/monorepo/package-fragment.json +13 -0
- package/templates/project-types/monorepo/pnpm-workspace.yaml +3 -0
- package/templates/project-types/monorepo/tsconfig.json.ejs +27 -0
- package/templates/project-types/scheduled-worker/package-fragment.json +5 -0
- package/templates/project-types/scheduled-worker/src/app.module.ts.ejs +13 -0
- package/templates/project-types/scheduled-worker/src/jobs/example.job.ts.ejs +12 -0
- package/templates/project-types/scheduled-worker/src/main.ts.ejs +10 -0
- package/templates/project-types/scheduled-worker/tests/unit/jobs/example.job.spec.ts +17 -0
- package/templates/recipes/adminjs/README.md +145 -0
- package/templates/recipes/adminjs/src/app/modules/admin/admin.module.ts +59 -0
- package/templates/recipes/adminjs/tests/unit/app/modules/admin/admin.module.spec.ts +22 -0
- package/templates/recipes/ai-context/README.md +11 -0
- package/templates/recipes/ai-context/claude/base.md +73 -0
- package/templates/recipes/ai-context/claude/commands/add-command.md +48 -0
- package/templates/recipes/ai-context/claude/commands/add-consumer.md +58 -0
- package/templates/recipes/ai-context/claude/commands/add-endpoint.md +69 -0
- package/templates/recipes/ai-context/claude/commands/add-job.md +42 -0
- package/templates/recipes/ai-context/claude/commands/migrate.md +69 -0
- package/templates/recipes/ai-context/copilot/base.md +71 -0
- package/templates/recipes/ai-context/cursor/auth.mdc +44 -0
- package/templates/recipes/ai-context/cursor/base.mdc +44 -0
- package/templates/recipes/ai-context/cursor/prisma.mdc +43 -0
- package/templates/recipes/ai-context/cursor/swagger.mdc +48 -0
- package/templates/recipes/ai-context/cursor/testing.mdc +58 -0
- package/templates/recipes/ai-context/cursor/typeorm.mdc +49 -0
- package/templates/recipes/api-keys/README.md +44 -0
- package/templates/recipes/api-keys/src/shared/guards/api-key.guard.ts +32 -0
- package/templates/recipes/api-keys/tests/unit/shared/guards/api-key.guard.spec.ts +40 -0
- package/templates/recipes/api-versioning/README.md +63 -0
- package/templates/recipes/audit-trail/README.md +75 -0
- package/templates/recipes/audit-trail/src/shared/decorators/auditable.decorator.ts +4 -0
- package/templates/recipes/audit-trail/src/shared/interceptors/audit.interceptor.ts +46 -0
- package/templates/recipes/audit-trail/tests/unit/shared/interceptors/audit.interceptor.spec.ts +82 -0
- package/templates/recipes/auth-flows/README.md +91 -0
- package/templates/recipes/auth-flows/src/app/modules/auth/auth.controller.ts +44 -0
- package/templates/recipes/auth-flows/src/app/modules/auth/auth.module.ts +11 -0
- package/templates/recipes/auth-flows/src/app/modules/auth/auth.service.ts +194 -0
- package/templates/recipes/auth-flows/src/app/modules/auth/dto/forgot-password.dto.ts +6 -0
- package/templates/recipes/auth-flows/src/app/modules/auth/dto/login.dto.ts +9 -0
- package/templates/recipes/auth-flows/src/app/modules/auth/dto/reset-password.dto.ts +11 -0
- package/templates/recipes/auth-flows/src/app/modules/auth/dto/signup.dto.ts +16 -0
- package/templates/recipes/auth-flows/tests/unit/app/modules/auth/auth.service.spec.ts +13 -0
- package/templates/recipes/bullmq/README.md +54 -0
- package/templates/recipes/bullmq/src/infrastructure/queue/example.processor.ts +25 -0
- package/templates/recipes/bullmq/src/infrastructure/queue/queue.module.ts +26 -0
- package/templates/recipes/bullmq/tests/unit/infrastructure/queue/example.processor.spec.ts +17 -0
- package/templates/recipes/changelog/.changelogrc.json +18 -0
- package/templates/recipes/changelog/README.md +44 -0
- package/templates/recipes/ci-cd/README.md +14 -0
- package/templates/recipes/ci-cd/aws-codepipeline/README.md +30 -0
- package/templates/recipes/ci-cd/aws-codepipeline/buildspec.yml +41 -0
- package/templates/recipes/ci-cd/azure-devops/README.md +32 -0
- package/templates/recipes/ci-cd/azure-devops/azure-pipelines.yml +79 -0
- package/templates/recipes/ci-cd/gcp-cloudbuild/README.md +64 -0
- package/templates/recipes/ci-cd/gcp-cloudbuild/cloudbuild.yaml +53 -0
- package/templates/recipes/ci-cd/github-actions/.github/workflows/cd.yml +35 -0
- package/templates/recipes/ci-cd/github-actions/.github/workflows/ci.yml +62 -0
- package/templates/recipes/ci-cd/github-actions/README.md +29 -0
- package/templates/recipes/circuit-breaker/README.md +45 -0
- package/templates/recipes/circuit-breaker/src/shared/utils/circuit-breaker.ts +100 -0
- package/templates/recipes/circuit-breaker/tests/unit/shared/utils/circuit-breaker.spec.ts +28 -0
- package/templates/recipes/cloud-aws/README.md +20 -0
- package/templates/recipes/cloud-aws/cloudfront/README.md +50 -0
- package/templates/recipes/cloud-aws/cloudfront/src/infrastructure/aws/cloudfront.module.ts +8 -0
- package/templates/recipes/cloud-aws/cloudfront/src/infrastructure/aws/cloudfront.service.ts +29 -0
- package/templates/recipes/cloud-aws/cloudwatch/README.md +40 -0
- package/templates/recipes/cloud-aws/cloudwatch/src/infrastructure/aws/cloudwatch.module.ts +8 -0
- package/templates/recipes/cloud-aws/cloudwatch/src/infrastructure/aws/cloudwatch.service.ts +40 -0
- package/templates/recipes/cloud-aws/cognito/README.md +39 -0
- package/templates/recipes/cloud-aws/cognito/src/infrastructure/aws/cognito.module.ts +8 -0
- package/templates/recipes/cloud-aws/cognito/src/infrastructure/aws/cognito.service.ts +47 -0
- package/templates/recipes/cloud-aws/dynamodb/README.md +48 -0
- package/templates/recipes/cloud-aws/dynamodb/src/infrastructure/aws/dynamodb.module.ts +8 -0
- package/templates/recipes/cloud-aws/dynamodb/src/infrastructure/aws/dynamodb.service.ts +49 -0
- package/templates/recipes/cloud-aws/elasticache/README.md +45 -0
- package/templates/recipes/cloud-aws/elasticache/src/infrastructure/aws/redis.module.ts +8 -0
- package/templates/recipes/cloud-aws/elasticache/src/infrastructure/aws/redis.service.ts +47 -0
- package/templates/recipes/cloud-aws/eventbridge/README.md +46 -0
- package/templates/recipes/cloud-aws/eventbridge/src/infrastructure/aws/eventbridge.module.ts +8 -0
- package/templates/recipes/cloud-aws/eventbridge/src/infrastructure/aws/eventbridge.service.ts +48 -0
- package/templates/recipes/cloud-aws/rds/README.md +59 -0
- package/templates/recipes/cloud-aws/s3/README.md +44 -0
- package/templates/recipes/cloud-aws/s3/src/infrastructure/aws/s3.module.ts +8 -0
- package/templates/recipes/cloud-aws/s3/src/infrastructure/aws/s3.service.ts +42 -0
- package/templates/recipes/cloud-aws/secrets-manager/README.md +38 -0
- package/templates/recipes/cloud-aws/secrets-manager/src/infrastructure/aws/secrets.module.ts +8 -0
- package/templates/recipes/cloud-aws/secrets-manager/src/infrastructure/aws/secrets.service.ts +39 -0
- package/templates/recipes/cloud-aws/sns/README.md +43 -0
- package/templates/recipes/cloud-aws/sns/src/infrastructure/aws/sns.module.ts +8 -0
- package/templates/recipes/cloud-aws/sns/src/infrastructure/aws/sns.service.ts +48 -0
- package/templates/recipes/cloud-aws/sqs/README.md +47 -0
- package/templates/recipes/cloud-aws/sqs/src/infrastructure/aws/sqs.module.ts +8 -0
- package/templates/recipes/cloud-aws/sqs/src/infrastructure/aws/sqs.service.ts +58 -0
- package/templates/recipes/cloud-aws/ssm/README.md +41 -0
- package/templates/recipes/cloud-aws/ssm/src/infrastructure/aws/ssm.module.ts +8 -0
- package/templates/recipes/cloud-aws/ssm/src/infrastructure/aws/ssm.service.ts +54 -0
- package/templates/recipes/cloud-azure/README.md +18 -0
- package/templates/recipes/cloud-azure/app-insights/README.md +50 -0
- package/templates/recipes/cloud-azure/app-insights/src/infrastructure/azure/app-insights.module.ts +11 -0
- package/templates/recipes/cloud-azure/app-insights/src/infrastructure/azure/app-insights.service.ts +38 -0
- package/templates/recipes/cloud-azure/blob-storage/README.md +49 -0
- package/templates/recipes/cloud-azure/blob-storage/src/infrastructure/azure/blob-storage.module.ts +11 -0
- package/templates/recipes/cloud-azure/blob-storage/src/infrastructure/azure/blob-storage.service.ts +64 -0
- package/templates/recipes/cloud-azure/cache/README.md +47 -0
- package/templates/recipes/cloud-azure/cache/src/infrastructure/azure/redis.module.ts +11 -0
- package/templates/recipes/cloud-azure/cache/src/infrastructure/azure/redis.service.ts +41 -0
- package/templates/recipes/cloud-azure/cosmos-db/README.md +57 -0
- package/templates/recipes/cloud-azure/cosmos-db/src/infrastructure/azure/cosmos-db.module.ts +11 -0
- package/templates/recipes/cloud-azure/cosmos-db/src/infrastructure/azure/cosmos-db.service.ts +55 -0
- package/templates/recipes/cloud-azure/entra-id/README.md +42 -0
- package/templates/recipes/cloud-azure/entra-id/src/infrastructure/azure/entra-id.module.ts +11 -0
- package/templates/recipes/cloud-azure/entra-id/src/infrastructure/azure/entra-id.service.ts +55 -0
- package/templates/recipes/cloud-azure/front-door/README.md +48 -0
- package/templates/recipes/cloud-azure/functions/README.md +48 -0
- package/templates/recipes/cloud-azure/key-vault/README.md +42 -0
- package/templates/recipes/cloud-azure/key-vault/src/infrastructure/azure/key-vault.module.ts +11 -0
- package/templates/recipes/cloud-azure/key-vault/src/infrastructure/azure/key-vault.service.ts +27 -0
- package/templates/recipes/cloud-azure/service-bus/README.md +49 -0
- package/templates/recipes/cloud-azure/service-bus/src/infrastructure/azure/service-bus.module.ts +11 -0
- package/templates/recipes/cloud-azure/service-bus/src/infrastructure/azure/service-bus.service.ts +52 -0
- package/templates/recipes/cloud-azure/sql-database/README.md +54 -0
- package/templates/recipes/cloud-gcp/README.md +18 -0
- package/templates/recipes/cloud-gcp/cloud-cdn/README.md +40 -0
- package/templates/recipes/cloud-gcp/cloud-functions/README.md +42 -0
- package/templates/recipes/cloud-gcp/cloud-logging/README.md +42 -0
- package/templates/recipes/cloud-gcp/cloud-logging/src/infrastructure/gcp/logging.module.ts +10 -0
- package/templates/recipes/cloud-gcp/cloud-logging/src/infrastructure/gcp/logging.service.ts +50 -0
- package/templates/recipes/cloud-gcp/cloud-sql/README.md +53 -0
- package/templates/recipes/cloud-gcp/cloud-storage/README.md +43 -0
- package/templates/recipes/cloud-gcp/cloud-storage/src/infrastructure/gcp/storage.module.ts +10 -0
- package/templates/recipes/cloud-gcp/cloud-storage/src/infrastructure/gcp/storage.service.ts +51 -0
- package/templates/recipes/cloud-gcp/firebase-auth/README.md +38 -0
- package/templates/recipes/cloud-gcp/firebase-auth/src/infrastructure/gcp/firebase-auth.module.ts +10 -0
- package/templates/recipes/cloud-gcp/firebase-auth/src/infrastructure/gcp/firebase-auth.service.ts +41 -0
- package/templates/recipes/cloud-gcp/firestore/README.md +46 -0
- package/templates/recipes/cloud-gcp/firestore/src/infrastructure/gcp/firestore.module.ts +10 -0
- package/templates/recipes/cloud-gcp/firestore/src/infrastructure/gcp/firestore.service.ts +44 -0
- package/templates/recipes/cloud-gcp/memorystore/README.md +44 -0
- package/templates/recipes/cloud-gcp/memorystore/src/infrastructure/gcp/redis.module.ts +10 -0
- package/templates/recipes/cloud-gcp/memorystore/src/infrastructure/gcp/redis.service.ts +54 -0
- package/templates/recipes/cloud-gcp/pubsub/README.md +43 -0
- package/templates/recipes/cloud-gcp/pubsub/src/infrastructure/gcp/pubsub.module.ts +10 -0
- package/templates/recipes/cloud-gcp/pubsub/src/infrastructure/gcp/pubsub.service.ts +60 -0
- package/templates/recipes/cloud-gcp/secret-manager/README.md +40 -0
- package/templates/recipes/cloud-gcp/secret-manager/src/infrastructure/gcp/secrets.module.ts +10 -0
- package/templates/recipes/cloud-gcp/secret-manager/src/infrastructure/gcp/secrets.service.ts +41 -0
- package/templates/recipes/config-validation/README.md +61 -0
- package/templates/recipes/config-validation/src/config/env.validation.ts +28 -0
- package/templates/recipes/config-validation/tests/unit/config/env.validation.spec.ts +34 -0
- package/templates/recipes/content-digest/README.md +28 -0
- package/templates/recipes/content-digest/src/shared/guards/content-digest.guard.ts +30 -0
- package/templates/recipes/content-digest/src/shared/interceptors/content-digest.interceptor.ts +23 -0
- package/templates/recipes/content-digest/tests/unit/shared/guards/content-digest.guard.spec.ts +56 -0
- package/templates/recipes/content-digest/tests/unit/shared/interceptors/content-digest.interceptor.spec.ts +54 -0
- package/templates/recipes/correlation-id/README.md +44 -0
- package/templates/recipes/correlation-id/src/shared/middleware/correlation-id.middleware.ts +29 -0
- package/templates/recipes/correlation-id/tests/unit/shared/middleware/correlation-id.spec.ts +5 -0
- package/templates/recipes/cors/README.md +45 -0
- package/templates/recipes/cqrs/README.md +39 -0
- package/templates/recipes/cqrs/src/shared/cqrs/example.command.ts +29 -0
- package/templates/recipes/cqrs/tests/unit/shared/cqrs/example.command.spec.ts +38 -0
- package/templates/recipes/csrf/README.md +55 -0
- package/templates/recipes/data-masking/README.md +85 -0
- package/templates/recipes/data-masking/src/shared/decorators/sensitive.decorator.ts +12 -0
- package/templates/recipes/data-masking/src/shared/utils/mask.util.ts +26 -0
- package/templates/recipes/data-masking/tests/unit/shared/utils/mask.util.spec.ts +21 -0
- package/templates/recipes/database-factories/README.md +48 -0
- package/templates/recipes/database-factories/tests/factories/base.factory.ts +51 -0
- package/templates/recipes/database-seeding/README.md +40 -0
- package/templates/recipes/database-seeding/src/infrastructure/database/seed.ts +61 -0
- package/templates/recipes/database-seeding/tests/unit/infrastructure/database/seed.spec.ts +37 -0
- package/templates/recipes/dead-letter-queue/README.md +79 -0
- package/templates/recipes/dead-letter-queue/src/infrastructure/queue/dlq.service.ts +43 -0
- package/templates/recipes/dead-letter-queue/tests/unit/infrastructure/queue/dlq.service.spec.ts +46 -0
- package/templates/recipes/dependabot-renovate/.github/dependabot.yml +52 -0
- package/templates/recipes/dependabot-renovate/README.md +37 -0
- package/templates/recipes/dependabot-renovate/renovate.json +46 -0
- package/templates/recipes/deploy/README.md +13 -0
- package/templates/recipes/deploy/docker-compose/README.md +38 -0
- package/templates/recipes/deploy/docker-compose/docker-compose.yml +43 -0
- package/templates/recipes/deploy/dockerfile/Dockerfile +30 -0
- package/templates/recipes/deploy/dockerfile/README.md +30 -0
- package/templates/recipes/deploy/dockerfile/dot-dockerignore +9 -0
- package/templates/recipes/deploy/kubernetes/README.md +43 -0
- package/templates/recipes/deploy/kubernetes/k8s/configmap.yaml +7 -0
- package/templates/recipes/deploy/kubernetes/k8s/deployment.yaml +45 -0
- package/templates/recipes/deploy/kubernetes/k8s/hpa.yaml +18 -0
- package/templates/recipes/deploy/kubernetes/k8s/ingress.yaml +23 -0
- package/templates/recipes/deploy/kubernetes/k8s/service.yaml +12 -0
- package/templates/recipes/deploy/serverless-framework/README.md +39 -0
- package/templates/recipes/deploy/serverless-framework/serverless.yml.ejs +22 -0
- package/templates/recipes/deploy/terraform/README.md +99 -0
- package/templates/recipes/deploy/terraform/main.tf.ejs +13 -0
- package/templates/recipes/deploy/terraform/modules/app/alb.tf +34 -0
- package/templates/recipes/deploy/terraform/modules/app/iam.tf +30 -0
- package/templates/recipes/deploy/terraform/modules/app/main.tf +80 -0
- package/templates/recipes/deploy/terraform/modules/app/outputs.tf +11 -0
- package/templates/recipes/deploy/terraform/modules/app/security.tf +37 -0
- package/templates/recipes/deploy/terraform/modules/app/variables.tf +42 -0
- package/templates/recipes/deploy/terraform/outputs.tf +4 -0
- package/templates/recipes/deploy/terraform/variables.tf +11 -0
- package/templates/recipes/devcontainer/.devcontainer/Dockerfile +5 -0
- package/templates/recipes/devcontainer/.devcontainer/devcontainer.json +32 -0
- package/templates/recipes/devcontainer/.devcontainer/docker-compose.yml +62 -0
- package/templates/recipes/devcontainer/README.md +31 -0
- package/templates/recipes/distributed-tracing/README.md +45 -0
- package/templates/recipes/distributed-tracing/src/shared/middleware/trace-propagation.middleware.ts +68 -0
- package/templates/recipes/distributed-tracing/tests/unit/shared/middleware/trace-propagation.middleware.spec.ts +76 -0
- package/templates/recipes/docker-compose-dev/Dockerfile.dev +14 -0
- package/templates/recipes/docker-compose-dev/README.md +57 -0
- package/templates/recipes/docker-compose-dev/docker-compose.dev.yml.ejs +54 -0
- package/templates/recipes/docs-site/README.md +41 -0
- package/templates/recipes/docs-site/docs/.vitepress/config.ts.ejs +53 -0
- package/templates/recipes/dpop/README.md +37 -0
- package/templates/recipes/dpop/src/shared/guards/dpop.guard.ts +61 -0
- package/templates/recipes/dpop/tests/unit/shared/guards/dpop.guard.spec.ts +69 -0
- package/templates/recipes/drizzle-postgres/README.md +68 -0
- package/templates/recipes/drizzle-postgres/drizzle.config.ts +10 -0
- package/templates/recipes/drizzle-postgres/src/infrastructure/database/drizzle.module.ts +25 -0
- package/templates/recipes/drizzle-postgres/src/infrastructure/database/schema/example.ts +9 -0
- package/templates/recipes/drizzle-postgres/src/infrastructure/database/schema/index.ts +3 -0
- package/templates/recipes/drizzle-postgres/tests/unit/infrastructure/database/drizzle.module.spec.ts +35 -0
- package/templates/recipes/env-per-environment/.env.development +17 -0
- package/templates/recipes/env-per-environment/.env.production +20 -0
- package/templates/recipes/env-per-environment/.env.test +17 -0
- package/templates/recipes/env-per-environment/README.md +40 -0
- package/templates/recipes/feature-flags/README.md +45 -0
- package/templates/recipes/feature-flags/src/shared/services/feature-flag.service.ts +48 -0
- package/templates/recipes/feature-flags/tests/unit/shared/services/feature-flag.service.spec.ts +36 -0
- package/templates/recipes/file-upload/README.md +104 -0
- package/templates/recipes/file-upload/src/shared/interceptors/file-upload.interceptor.ts +33 -0
- package/templates/recipes/file-upload/src/shared/pipes/file-validation.pipe.ts +45 -0
- package/templates/recipes/file-upload/tests/unit/shared/pipes/file-validation.pipe.spec.ts +56 -0
- package/templates/recipes/filtering/README.md +43 -0
- package/templates/recipes/filtering/src/shared/dto/filter.dto.ts +49 -0
- package/templates/recipes/filtering/tests/unit/shared/dto/filter.dto.spec.ts +38 -0
- package/templates/recipes/graceful-shutdown/README.md +60 -0
- package/templates/recipes/graceful-shutdown/src/shared/lifecycle/shutdown.service.ts +52 -0
- package/templates/recipes/graceful-shutdown/tests/unit/shared/lifecycle/shutdown.service.spec.ts +52 -0
- package/templates/recipes/graphql-mercurius/README.md +37 -0
- package/templates/recipes/graphql-mercurius/src/infrastructure/graphql/graphql.module.ts +18 -0
- package/templates/recipes/graphql-mercurius/tests/unit/infrastructure/graphql/graphql.module.spec.ts +12 -0
- package/templates/recipes/health-checks/README.md +35 -0
- package/templates/recipes/health-checks/src/shared/health/health.controller.ts +26 -0
- package/templates/recipes/health-checks/src/shared/health/health.module.ts +9 -0
- package/templates/recipes/health-checks/tests/unit/shared/health/health.controller.spec.ts +8 -0
- package/templates/recipes/helmet/README.md +43 -0
- package/templates/recipes/http-caching/README.md +63 -0
- package/templates/recipes/http-caching/src/shared/decorators/cache-control.decorator.ts +18 -0
- package/templates/recipes/http-caching/src/shared/interceptors/cache-control.interceptor.ts +43 -0
- package/templates/recipes/http-caching/tests/unit/shared/interceptors/cache-control.interceptor.spec.ts +44 -0
- package/templates/recipes/i18n/README.md +45 -0
- package/templates/recipes/i18n/src/i18n/en/common.json +7 -0
- package/templates/recipes/i18n/src/i18n/nl/common.json +7 -0
- package/templates/recipes/i18n/src/shared/i18n/i18n.module.ts +17 -0
- package/templates/recipes/i18n/tests/unit/shared/i18n/i18n.module.spec.ts +18 -0
- package/templates/recipes/idempotency/README.md +63 -0
- package/templates/recipes/idempotency/src/shared/decorators/idempotent.decorator.ts +4 -0
- package/templates/recipes/idempotency/src/shared/middleware/idempotency.middleware.ts +63 -0
- package/templates/recipes/idempotency/tests/unit/shared/middleware/idempotency.middleware.spec.ts +56 -0
- package/templates/recipes/json-merge-patch/README.md +53 -0
- package/templates/recipes/json-merge-patch/src/shared/pipes/merge-patch.pipe.ts +11 -0
- package/templates/recipes/json-merge-patch/tests/unit/shared/pipes/merge-patch.pipe.spec.ts +30 -0
- package/templates/recipes/json-patch/README.md +54 -0
- package/templates/recipes/json-patch/src/shared/pipes/json-patch.pipe.ts +39 -0
- package/templates/recipes/json-patch/tests/unit/shared/pipes/json-patch.pipe.spec.ts +37 -0
- package/templates/recipes/jwt-auth/README.md +56 -0
- package/templates/recipes/jwt-auth/src/shared/decorators/current-user.decorator.ts +10 -0
- package/templates/recipes/jwt-auth/src/shared/decorators/public.decorator.ts +4 -0
- package/templates/recipes/jwt-auth/src/shared/guards/jwt-auth.guard.ts +24 -0
- package/templates/recipes/jwt-auth/tests/unit/shared/guards/jwt-auth.guard.spec.ts +9 -0
- package/templates/recipes/kysely/README.md +53 -0
- package/templates/recipes/kysely/src/infrastructure/database/database.module.ts +28 -0
- package/templates/recipes/kysely/src/infrastructure/database/types.ts +17 -0
- package/templates/recipes/kysely/tests/unit/infrastructure/database/database.module.spec.ts +35 -0
- package/templates/recipes/license/LICENSE.agpl3 +59 -0
- package/templates/recipes/license/LICENSE.apache +189 -0
- package/templates/recipes/license/LICENSE.bsd3 +28 -0
- package/templates/recipes/license/LICENSE.gpl3 +22 -0
- package/templates/recipes/license/LICENSE.isc +15 -0
- package/templates/recipes/license/LICENSE.mit +21 -0
- package/templates/recipes/license/LICENSE.mpl2 +24 -0
- package/templates/recipes/license/LICENSE.proprietary +76 -0
- package/templates/recipes/license/LICENSE.unlicensed +13 -0
- package/templates/recipes/license/README.md +53 -0
- package/templates/recipes/load-testing/README.md +77 -0
- package/templates/recipes/load-testing/k6/smoke.js +20 -0
- package/templates/recipes/load-testing/k6/stress.js +22 -0
- package/templates/recipes/mfa-totp/README.md +77 -0
- package/templates/recipes/mfa-totp/src/shared/auth/totp.service.ts +26 -0
- package/templates/recipes/mfa-totp/tests/unit/shared/auth/totp.service.spec.ts +65 -0
- package/templates/recipes/mikro-orm/README.md +22 -0
- package/templates/recipes/mikro-orm/src/infrastructure/database/database.module.ts +8 -0
- package/templates/recipes/mikro-orm/src/infrastructure/database/entities/.gitkeep +0 -0
- package/templates/recipes/mikro-orm/src/infrastructure/database/migrations/.gitkeep +0 -0
- package/templates/recipes/mikro-orm/src/infrastructure/database/mikro-orm.config.ts +20 -0
- package/templates/recipes/mikro-orm/tests/unit/infrastructure/database/mikro-orm.config.spec.ts +53 -0
- package/templates/recipes/mongoose/README.md +42 -0
- package/templates/recipes/mongoose/src/infrastructure/database/database.module.ts.ejs +17 -0
- package/templates/recipes/mongoose/tests/unit/infrastructure/database/database.module.spec.ts +25 -0
- package/templates/recipes/multi-tenancy/README.md +49 -0
- package/templates/recipes/multi-tenancy/src/shared/decorators/tenant.decorator.ts +14 -0
- package/templates/recipes/multi-tenancy/src/shared/middleware/tenant.middleware.ts +49 -0
- package/templates/recipes/multi-tenancy/tests/unit/shared/middleware/tenant.middleware.spec.ts +29 -0
- package/templates/recipes/nodemailer/README.md +55 -0
- package/templates/recipes/nodemailer/src/infrastructure/notifications/mail.module.ts +37 -0
- package/templates/recipes/nodemailer/tests/unit/infrastructure/notifications/mail.module.spec.ts +33 -0
- package/templates/recipes/oauth-apple/README.md +68 -0
- package/templates/recipes/oauth-apple/src/shared/auth/apple-auth.guard.ts +5 -0
- package/templates/recipes/oauth-apple/src/shared/auth/apple.strategy.ts +33 -0
- package/templates/recipes/oauth-apple/tests/unit/shared/auth/apple.strategy.spec.ts +65 -0
- package/templates/recipes/oauth-github/README.md +62 -0
- package/templates/recipes/oauth-github/src/shared/auth/github-auth.guard.ts +5 -0
- package/templates/recipes/oauth-github/src/shared/auth/github.strategy.ts +33 -0
- package/templates/recipes/oauth-github/tests/unit/shared/auth/github.strategy.spec.ts +72 -0
- package/templates/recipes/oauth-google/README.md +64 -0
- package/templates/recipes/oauth-google/src/shared/auth/google-auth.guard.ts +5 -0
- package/templates/recipes/oauth-google/src/shared/auth/google.strategy.ts +33 -0
- package/templates/recipes/oauth-google/tests/unit/shared/auth/google.strategy.spec.ts +72 -0
- package/templates/recipes/oauth2-introspection/README.md +62 -0
- package/templates/recipes/oauth2-introspection/src/shared/guards/token-introspection.guard.ts +77 -0
- package/templates/recipes/oauth2-introspection/tests/unit/shared/guards/token-introspection.guard.spec.ts +99 -0
- package/templates/recipes/opentelemetry/README.md +44 -0
- package/templates/recipes/opentelemetry/src/infrastructure/telemetry/tracing.ts +38 -0
- package/templates/recipes/opentelemetry/tests/unit/infrastructure/telemetry/tracing.spec.ts +23 -0
- package/templates/recipes/pagination/README.md +71 -0
- package/templates/recipes/pagination/src/shared/decorators/paginate.decorator.ts +25 -0
- package/templates/recipes/pagination/src/shared/dto/pagination.dto.ts +64 -0
- package/templates/recipes/pagination/src/shared/interceptors/pagination-link.interceptor.ts +31 -0
- package/templates/recipes/pagination/tests/unit/shared/dto/pagination.dto.spec.ts +56 -0
- package/templates/recipes/passport/README.md +41 -0
- package/templates/recipes/passport/src/shared/guards/local-auth.guard.ts +5 -0
- package/templates/recipes/passport/tests/unit/shared/guards/local-auth.guard.spec.ts +17 -0
- package/templates/recipes/pino/README.md +48 -0
- package/templates/recipes/pino/src/infrastructure/logging/logger.module.ts +39 -0
- package/templates/recipes/pino/tests/unit/infrastructure/logging/logger.module.spec.ts +6 -0
- package/templates/recipes/prefer-header/README.md +92 -0
- package/templates/recipes/prefer-header/src/shared/interceptors/prefer.interceptor.ts +60 -0
- package/templates/recipes/prefer-header/tests/unit/shared/interceptors/prefer.interceptor.spec.ts +44 -0
- package/templates/recipes/prisma/README.md +52 -0
- package/templates/recipes/prisma/prisma/schema.prisma.ejs +8 -0
- package/templates/recipes/prisma/src/infrastructure/database/prisma.service.ts +27 -0
- package/templates/recipes/prisma/tests/unit/infrastructure/database/prisma.service.spec.ts +21 -0
- package/templates/recipes/prometheus/README.md +54 -0
- package/templates/recipes/prometheus/src/infrastructure/metrics/metrics.controller.ts +15 -0
- package/templates/recipes/prometheus/src/infrastructure/metrics/metrics.module.ts +29 -0
- package/templates/recipes/prometheus/tests/unit/infrastructure/metrics/metrics.controller.spec.ts +22 -0
- package/templates/recipes/rabbitmq/README.md +53 -0
- package/templates/recipes/rabbitmq/src/infrastructure/queue/queue.module.ts.ejs +27 -0
- package/templates/recipes/rbac-casl/README.md +69 -0
- package/templates/recipes/rbac-casl/src/shared/auth/casl-ability.factory.ts +43 -0
- package/templates/recipes/rbac-casl/src/shared/decorators/roles.decorator.ts +5 -0
- package/templates/recipes/rbac-casl/src/shared/guards/policies.guard.ts +32 -0
- package/templates/recipes/rbac-casl/src/shared/guards/roles.guard.ts +21 -0
- package/templates/recipes/rbac-casl/tests/unit/shared/auth/casl-ability.factory.spec.ts +6 -0
- package/templates/recipes/redis-cache/README.md +55 -0
- package/templates/recipes/redis-cache/src/infrastructure/cache/cache.module.ts +26 -0
- package/templates/recipes/redis-cache/tests/unit/infrastructure/cache/cache.module.spec.ts +12 -0
- package/templates/recipes/request-context/README.md +57 -0
- package/templates/recipes/request-context/src/shared/context/request-context.module.ts +19 -0
- package/templates/recipes/request-context/tests/unit/shared/context/request-context.module.spec.ts +20 -0
- package/templates/recipes/request-logging/README.md +36 -0
- package/templates/recipes/request-logging/src/shared/middleware/request-logging.middleware.ts +40 -0
- package/templates/recipes/request-logging/tests/unit/shared/middleware/request-logging.middleware.spec.ts +64 -0
- package/templates/recipes/s3-minio/README.md +52 -0
- package/templates/recipes/s3-minio/src/infrastructure/storage/storage.module.ts +10 -0
- package/templates/recipes/s3-minio/src/infrastructure/storage/storage.service.ts +72 -0
- package/templates/recipes/s3-minio/tests/unit/infrastructure/storage/storage.service.spec.ts +23 -0
- package/templates/recipes/sdk-generation/README.md +40 -0
- package/templates/recipes/sdk-generation/openapitools.json +21 -0
- package/templates/recipes/sendgrid/README.md +45 -0
- package/templates/recipes/sendgrid/src/infrastructure/notifications/sendgrid.service.ts +60 -0
- package/templates/recipes/sendgrid/tests/unit/infrastructure/notifications/sendgrid.service.spec.ts +59 -0
- package/templates/recipes/sentry/README.md +49 -0
- package/templates/recipes/sentry/src/infrastructure/sentry/sentry.filter.ts +34 -0
- package/templates/recipes/sentry/src/infrastructure/sentry/sentry.module.ts +23 -0
- package/templates/recipes/sentry/tests/unit/infrastructure/sentry/sentry.filter.spec.ts +50 -0
- package/templates/recipes/seq2/README.md +41 -0
- package/templates/recipes/seq2/src/infrastructure/logging/seq.transport.ts +57 -0
- package/templates/recipes/seq2/tests/unit/infrastructure/logging/seq.transport.spec.ts +53 -0
- package/templates/recipes/serialization-groups/README.md +105 -0
- package/templates/recipes/serialization-groups/src/shared/interceptors/serialize.interceptor.ts +29 -0
- package/templates/recipes/serialization-groups/tests/unit/shared/interceptors/serialize.interceptor.spec.ts +48 -0
- package/templates/recipes/soft-delete/README.md +71 -0
- package/templates/recipes/soft-delete/src/shared/decorators/with-deleted.decorator.ts +4 -0
- package/templates/recipes/soft-delete/src/shared/entities/soft-deletable.entity.ts +20 -0
- package/templates/recipes/soft-delete/tests/unit/shared/entities/soft-deletable.entity.spec.ts +35 -0
- package/templates/recipes/sse/README.md +43 -0
- package/templates/recipes/sse/src/shared/gateways/events.sse.controller.ts +21 -0
- package/templates/recipes/sse/tests/unit/shared/gateways/events.sse.controller.spec.ts +32 -0
- package/templates/recipes/swagger/README.md +42 -0
- package/templates/recipes/swagger/src/main.swagger.ts.ejs +20 -0
- package/templates/recipes/swagger/tests/unit/main.swagger.spec.ts +5 -0
- package/templates/recipes/throttler/README.md +49 -0
- package/templates/recipes/throttler/src/shared/guards/throttle.config.ts +33 -0
- package/templates/recipes/throttler/tests/unit/shared/guards/throttle.spec.ts +5 -0
- package/templates/recipes/transactional-outbox/README.md +98 -0
- package/templates/recipes/transactional-outbox/src/infrastructure/outbox/outbox.entity.ts +30 -0
- package/templates/recipes/transactional-outbox/src/infrastructure/outbox/outbox.service.ts +21 -0
- package/templates/recipes/transactional-outbox/tests/unit/infrastructure/outbox/outbox.service.spec.ts +38 -0
- package/templates/recipes/typeorm-mysql/README.md +48 -0
- package/templates/recipes/typeorm-mysql/src/infrastructure/database/database.module.ts.ejs +24 -0
- package/templates/recipes/typeorm-postgres/README.md +101 -0
- package/templates/recipes/typeorm-postgres/src/infrastructure/database/data-source.ts.ejs +14 -0
- package/templates/recipes/typeorm-postgres/src/infrastructure/database/database.module.ts.ejs +24 -0
- package/templates/recipes/typeorm-postgres/src/infrastructure/database/entities/.gitkeep +0 -0
- package/templates/recipes/typeorm-postgres/src/infrastructure/database/entities/index.ts +7 -0
- package/templates/recipes/typeorm-postgres/src/infrastructure/database/migrations/.gitkeep +0 -0
- package/templates/recipes/typeorm-postgres/src/infrastructure/database/migrations/index.ts +10 -0
- package/templates/recipes/typeorm-postgres/tests/unit/infrastructure/database/database.module.spec.ts +11 -0
- package/templates/recipes/webhooks/README.md +76 -0
- package/templates/recipes/webhooks/src/infrastructure/webhooks/webhook.service.ts +53 -0
- package/templates/recipes/webhooks/tests/unit/infrastructure/webhooks/webhook.service.spec.ts +31 -0
- package/templates/recipes/websockets/README.md +44 -0
- package/templates/recipes/websockets/src/shared/gateways/events.gateway.ts +55 -0
- package/templates/recipes/websockets/tests/unit/shared/gateways/events.gateway.spec.ts +23 -0
- package/templates/recipes/winston/README.md +45 -0
- package/templates/recipes/winston/src/infrastructure/logging/logger.module.ts +34 -0
- package/templates/recipes/winston/tests/unit/infrastructure/logging/logger.module.spec.ts +12 -0
- package/templates/recipes/worker-threads/README.md +71 -0
- package/templates/recipes/worker-threads/src/shared/utils/worker-pool.ts +59 -0
- package/templates/recipes/worker-threads/tests/unit/shared/utils/worker-pool.spec.ts +36 -0
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
GNU GENERAL PUBLIC LICENSE
|
|
2
|
+
Version 3, 29 June 2007
|
|
3
|
+
|
|
4
|
+
Copyright (C) 2007 Free Software Foundation, Inc. <https://fsf.org/>
|
|
5
|
+
Everyone is permitted to copy and distribute verbatim copies
|
|
6
|
+
of this license document, but changing it is not allowed.
|
|
7
|
+
|
|
8
|
+
Preamble
|
|
9
|
+
|
|
10
|
+
The GNU General Public License is a free, copyleft license for
|
|
11
|
+
software and other kinds of works.
|
|
12
|
+
|
|
13
|
+
The licenses for most software and other practical works are designed
|
|
14
|
+
to take away your freedom to share and change the works. By contrast,
|
|
15
|
+
the GNU General Public License is intended to guarantee your freedom to
|
|
16
|
+
share and change all versions of a program--to make sure it remains free
|
|
17
|
+
software for all its users. We, the Free Software Foundation, use the
|
|
18
|
+
GNU General Public License for most of our software; it applies also to
|
|
19
|
+
any other work released this way by its authors. You can apply it to
|
|
20
|
+
your programs, too.
|
|
21
|
+
|
|
22
|
+
For the full license text, see: https://www.gnu.org/licenses/gpl-3.0.txt
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
ISC License
|
|
2
|
+
|
|
3
|
+
Copyright (c) [year] [fullname]
|
|
4
|
+
|
|
5
|
+
Permission to use, copy, modify, and/or distribute this software for any
|
|
6
|
+
purpose with or without fee is hereby granted, provided that the above
|
|
7
|
+
copyright notice and this permission notice appear in all copies.
|
|
8
|
+
|
|
9
|
+
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
|
|
10
|
+
REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
|
|
11
|
+
AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
|
|
12
|
+
INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
|
|
13
|
+
LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
|
|
14
|
+
OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
|
15
|
+
PERFORMANCE OF THIS SOFTWARE.
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) [year] [fullname]
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
Mozilla Public License Version 2.0
|
|
2
|
+
==================================
|
|
3
|
+
|
|
4
|
+
1. Definitions
|
|
5
|
+
--------------
|
|
6
|
+
|
|
7
|
+
1.1. "Contributor"
|
|
8
|
+
means each individual or legal entity that creates, contributes to
|
|
9
|
+
the creation of, or owns Covered Software.
|
|
10
|
+
|
|
11
|
+
1.2. "Contributor Version"
|
|
12
|
+
means the combination of the Contributions of others (if any) used
|
|
13
|
+
by a Contributor and that particular Contributor's Contribution.
|
|
14
|
+
|
|
15
|
+
1.3. "Contribution"
|
|
16
|
+
means Covered Software of a particular Contributor.
|
|
17
|
+
|
|
18
|
+
1.4. "Covered Software"
|
|
19
|
+
means Source Code Form to which the initial Contributor has attached
|
|
20
|
+
the notice in Exhibit A, the Executable Form of such Source Code
|
|
21
|
+
Form, and Modifications of such Source Code Form, in each case
|
|
22
|
+
including portions thereof.
|
|
23
|
+
|
|
24
|
+
For the full license text, see: https://www.mozilla.org/en-US/MPL/2.0/
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
BBJ Systems Holding Proprietary License
|
|
2
|
+
Version 1.0
|
|
3
|
+
|
|
4
|
+
Copyright (c) [year] BBJ Systems Holding. All rights reserved.
|
|
5
|
+
|
|
6
|
+
1. DEFINITIONS
|
|
7
|
+
|
|
8
|
+
"Software" means the source code, object code, documentation, and any
|
|
9
|
+
associated materials provided under this license.
|
|
10
|
+
|
|
11
|
+
"Licensee" means the individual or entity that has been granted a license
|
|
12
|
+
to use the Software by BBJ Systems Holding.
|
|
13
|
+
|
|
14
|
+
"Authorized Purpose" means internal business use by the Licensee, including
|
|
15
|
+
development, testing, and deployment of applications built using the Software.
|
|
16
|
+
|
|
17
|
+
2. GRANT OF LICENSE
|
|
18
|
+
|
|
19
|
+
Subject to the terms of this license, BBJ Systems Holding grants the Licensee a
|
|
20
|
+
non-exclusive, non-transferable, revocable license to use the Software solely
|
|
21
|
+
for the Authorized Purpose.
|
|
22
|
+
|
|
23
|
+
3. RESTRICTIONS
|
|
24
|
+
|
|
25
|
+
The Licensee SHALL NOT:
|
|
26
|
+
|
|
27
|
+
a) Redistribute, sublicense, sell, lease, or otherwise transfer the Software
|
|
28
|
+
or any portion thereof to any third party.
|
|
29
|
+
|
|
30
|
+
b) Modify, adapt, translate, reverse engineer, decompile, or disassemble the
|
|
31
|
+
Software, except to the extent expressly permitted by applicable law.
|
|
32
|
+
|
|
33
|
+
c) Remove, alter, or obscure any proprietary notices, labels, or marks on
|
|
34
|
+
the Software.
|
|
35
|
+
|
|
36
|
+
d) Use the Software to create a competing product or service.
|
|
37
|
+
|
|
38
|
+
e) Use the Software in any manner that violates applicable laws or regulations.
|
|
39
|
+
|
|
40
|
+
4. INTELLECTUAL PROPERTY
|
|
41
|
+
|
|
42
|
+
The Software and all copies thereof are proprietary to BBJ Systems Holding and
|
|
43
|
+
title thereto remains in BBJ Systems Holding. All applicable rights to patents,
|
|
44
|
+
copyrights, trademarks, and trade secrets in the Software are and shall
|
|
45
|
+
remain in BBJ Systems Holding.
|
|
46
|
+
|
|
47
|
+
5. CONFIDENTIALITY
|
|
48
|
+
|
|
49
|
+
The Licensee agrees to maintain the confidentiality of the Software and not
|
|
50
|
+
to disclose the Software to any third party without the prior written consent
|
|
51
|
+
of BBJ Systems Holding.
|
|
52
|
+
|
|
53
|
+
6. WARRANTY DISCLAIMER
|
|
54
|
+
|
|
55
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
56
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
57
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
|
58
|
+
BBJ SYSTEMS HOLDING BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
|
59
|
+
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
|
60
|
+
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
61
|
+
|
|
62
|
+
7. TERMINATION
|
|
63
|
+
|
|
64
|
+
This license is effective until terminated. BBJ Systems Holding may terminate
|
|
65
|
+
this license at any time if the Licensee breaches any provision hereof.
|
|
66
|
+
Upon termination, the Licensee must destroy all copies of the Software in
|
|
67
|
+
their possession.
|
|
68
|
+
|
|
69
|
+
8. GOVERNING LAW
|
|
70
|
+
|
|
71
|
+
This license shall be governed by and construed in accordance with the laws
|
|
72
|
+
of the Netherlands, without regard to its conflict of laws principles.
|
|
73
|
+
|
|
74
|
+
9. CONTACT
|
|
75
|
+
|
|
76
|
+
For licensing inquiries: licensing@example.com
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
UNLICENSED
|
|
2
|
+
|
|
3
|
+
Copyright (c) [year] [fullname]
|
|
4
|
+
|
|
5
|
+
All rights reserved.
|
|
6
|
+
|
|
7
|
+
This software and associated documentation files (the "Software") may not be
|
|
8
|
+
used, copied, modified, merged, published, distributed, sublicensed, or sold
|
|
9
|
+
without the express written permission of the copyright holder.
|
|
10
|
+
|
|
11
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
12
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
13
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
# License Templates
|
|
2
|
+
|
|
3
|
+
License file templates for generated projects. The CLI prompts for license selection during scaffolding.
|
|
4
|
+
|
|
5
|
+
## Links
|
|
6
|
+
|
|
7
|
+
- [Choose a License](https://choosealicense.com/)
|
|
8
|
+
- [SPDX License List](https://spdx.org/licenses/)
|
|
9
|
+
- [Open Source Initiative](https://opensource.org/licenses)
|
|
10
|
+
- [GNU Licenses](https://www.gnu.org/licenses/)
|
|
11
|
+
|
|
12
|
+
## Available Licenses
|
|
13
|
+
|
|
14
|
+
| License | File | SPDX ID | Type |
|
|
15
|
+
| -------------------------------- | -------------------- | ----------------------- | ---------------- |
|
|
16
|
+
| MIT | `LICENSE.mit` | `MIT` | Permissive |
|
|
17
|
+
| Apache 2.0 | `LICENSE.apache` | `Apache-2.0` | Permissive |
|
|
18
|
+
| ISC | `LICENSE.isc` | `ISC` | Permissive |
|
|
19
|
+
| BSD 3-Clause | `LICENSE.bsd3` | `BSD-3-Clause` | Permissive |
|
|
20
|
+
| Mozilla Public License 2.0 | `LICENSE.mpl2` | `MPL-2.0` | Weak copyleft |
|
|
21
|
+
| GNU GPL v3 | `LICENSE.gpl3` | `GPL-3.0-only` | Strong copyleft |
|
|
22
|
+
| GNU AGPL v3 | `LICENSE.agpl3` | `AGPL-3.0-only` | Network copyleft |
|
|
23
|
+
| Proprietary | `LICENSE.proprietary` | `LicenseRef-Proprietary` | Proprietary |
|
|
24
|
+
| Unlicensed (All Rights Reserved) | `LICENSE.unlicensed` | `UNLICENSED` | Proprietary |
|
|
25
|
+
|
|
26
|
+
## Usage
|
|
27
|
+
|
|
28
|
+
The selected license is copied to your project root as `LICENSE`:
|
|
29
|
+
|
|
30
|
+
```bash
|
|
31
|
+
# Example: MIT
|
|
32
|
+
cp LICENSE.mit LICENSE
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
Replace `[year]` and `[fullname]` placeholders with your values.
|
|
36
|
+
|
|
37
|
+
## When to Use Each
|
|
38
|
+
|
|
39
|
+
| Use Case | Recommended License |
|
|
40
|
+
| ------------------------------------------ | ---------------------- |
|
|
41
|
+
| Open source library (max adoption) | MIT or ISC |
|
|
42
|
+
| Open source with patent protection | Apache 2.0 |
|
|
43
|
+
| Open source, file-level copyleft | MPL 2.0 |
|
|
44
|
+
| Open source, full copyleft | GPL v3 |
|
|
45
|
+
| SaaS/network service, force source sharing | AGPL v3 |
|
|
46
|
+
| Internal proprietary projects | Proprietary |
|
|
47
|
+
| Client projects (no open source) | Unlicensed |
|
|
48
|
+
|
|
49
|
+
## Generated Files
|
|
50
|
+
|
|
51
|
+
| File | Description |
|
|
52
|
+
| --------- | ------------------------- |
|
|
53
|
+
| `LICENSE` | The selected license text |
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
# Load Testing (k6)
|
|
2
|
+
|
|
3
|
+
Performance and load testing with Grafana k6.
|
|
4
|
+
|
|
5
|
+
## Links
|
|
6
|
+
|
|
7
|
+
- [k6 Documentation](https://grafana.com/docs/k6/)
|
|
8
|
+
- [k6 Installation](https://grafana.com/docs/k6/latest/set-up/install-k6/)
|
|
9
|
+
- [k6 on GitHub](https://github.com/grafana/k6)
|
|
10
|
+
|
|
11
|
+
## Installation
|
|
12
|
+
|
|
13
|
+
k6 is a standalone Go binary. It is not an npm dependency.
|
|
14
|
+
|
|
15
|
+
```bash
|
|
16
|
+
# macOS
|
|
17
|
+
brew install k6
|
|
18
|
+
|
|
19
|
+
# Debian / Ubuntu
|
|
20
|
+
sudo gpg -k
|
|
21
|
+
sudo gpg --no-default-keyring --keyring /usr/share/keyrings/k6-archive-keyring.gpg \
|
|
22
|
+
--keyserver hkp://keyserver.ubuntu.com:80 --recv-keys C5AD17C747E3415A3642D57D77C6C491D6AC1D69
|
|
23
|
+
echo "deb [signed-by=/usr/share/keyrings/k6-archive-keyring.gpg] https://dl.k6.io/deb stable main" \
|
|
24
|
+
| sudo tee /etc/apt/sources.list.d/k6.list
|
|
25
|
+
sudo apt-get update && sudo apt-get install k6
|
|
26
|
+
|
|
27
|
+
# Docker
|
|
28
|
+
docker run --rm -i grafana/k6 run - <k6/smoke.js
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
## Usage
|
|
32
|
+
|
|
33
|
+
### Smoke Test
|
|
34
|
+
|
|
35
|
+
Verifies the system works under minimal load (1 virtual user, 10 seconds).
|
|
36
|
+
|
|
37
|
+
```bash
|
|
38
|
+
k6 run k6/smoke.js
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
### Stress Test
|
|
42
|
+
|
|
43
|
+
Ramps load from 50 to 100 virtual users over 9 minutes to find breaking points.
|
|
44
|
+
|
|
45
|
+
```bash
|
|
46
|
+
k6 run k6/stress.js
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
### Spike Test
|
|
50
|
+
|
|
51
|
+
To create a spike test, copy an existing script and configure a sharp ramp:
|
|
52
|
+
|
|
53
|
+
```javascript
|
|
54
|
+
export const options = {
|
|
55
|
+
stages: [
|
|
56
|
+
{ duration: '10s', target: 200 },
|
|
57
|
+
{ duration: '1m', target: 200 },
|
|
58
|
+
{ duration: '10s', target: 0 },
|
|
59
|
+
],
|
|
60
|
+
};
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
## Thresholds
|
|
64
|
+
|
|
65
|
+
Each test defines thresholds that cause k6 to exit with a non-zero code if they are breached:
|
|
66
|
+
|
|
67
|
+
| Metric | Smoke | Stress |
|
|
68
|
+
| ------------------- | ----------- | ------------ |
|
|
69
|
+
| `http_req_duration` | p95 < 500ms | p95 < 1000ms |
|
|
70
|
+
| `http_req_failed` | < 1% | < 5% |
|
|
71
|
+
|
|
72
|
+
## Generated Files
|
|
73
|
+
|
|
74
|
+
| File | Description |
|
|
75
|
+
| -------------- | -------------------------------------------- |
|
|
76
|
+
| `k6/smoke.js` | Smoke test — minimal load, strict thresholds |
|
|
77
|
+
| `k6/stress.js` | Stress test — ramp to 100 VUs over 9 minutes |
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import http from 'k6/http';
|
|
2
|
+
import { check, sleep } from 'k6';
|
|
3
|
+
|
|
4
|
+
export const options = {
|
|
5
|
+
vus: 1,
|
|
6
|
+
duration: '10s',
|
|
7
|
+
thresholds: {
|
|
8
|
+
http_req_duration: ['p(95)<500'],
|
|
9
|
+
http_req_failed: ['rate<0.01'],
|
|
10
|
+
},
|
|
11
|
+
};
|
|
12
|
+
|
|
13
|
+
export default function () {
|
|
14
|
+
const res = http.get('http://localhost:3000/health');
|
|
15
|
+
check(res, {
|
|
16
|
+
'status is 200': (r) => r.status === 200,
|
|
17
|
+
'response time < 200ms': (r) => r.timings.duration < 200,
|
|
18
|
+
});
|
|
19
|
+
sleep(1);
|
|
20
|
+
}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import http from 'k6/http';
|
|
2
|
+
import { check, sleep } from 'k6';
|
|
3
|
+
|
|
4
|
+
export const options = {
|
|
5
|
+
stages: [
|
|
6
|
+
{ duration: '1m', target: 50 },
|
|
7
|
+
{ duration: '3m', target: 50 },
|
|
8
|
+
{ duration: '1m', target: 100 },
|
|
9
|
+
{ duration: '3m', target: 100 },
|
|
10
|
+
{ duration: '1m', target: 0 },
|
|
11
|
+
],
|
|
12
|
+
thresholds: {
|
|
13
|
+
http_req_duration: ['p(95)<1000'],
|
|
14
|
+
http_req_failed: ['rate<0.05'],
|
|
15
|
+
},
|
|
16
|
+
};
|
|
17
|
+
|
|
18
|
+
export default function () {
|
|
19
|
+
const res = http.get('http://localhost:3000/health');
|
|
20
|
+
check(res, { 'status is 200': (r) => r.status === 200 });
|
|
21
|
+
sleep(0.5);
|
|
22
|
+
}
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
# Two-Factor Authentication (TOTP)
|
|
2
|
+
|
|
3
|
+
TOTP-based two-factor authentication with QR code setup and backup codes.
|
|
4
|
+
|
|
5
|
+
## Links
|
|
6
|
+
|
|
7
|
+
- [otplib on npm](https://www.npmjs.com/package/otplib)
|
|
8
|
+
- [otplib on GitHub](https://github.com/yeojz/otplib)
|
|
9
|
+
- [qrcode on npm](https://www.npmjs.com/package/qrcode)
|
|
10
|
+
- [RFC 6238 — TOTP Algorithm](https://datatracker.ietf.org/doc/html/rfc6238)
|
|
11
|
+
- [RFC 4226 — HOTP Algorithm](https://datatracker.ietf.org/doc/html/rfc4226)
|
|
12
|
+
|
|
13
|
+
## Dependencies
|
|
14
|
+
|
|
15
|
+
| Package | Version | Purpose |
|
|
16
|
+
| --------------- | -------- | --------------------------------- |
|
|
17
|
+
| `otplib` | `12.0.1` | TOTP/HOTP token generation |
|
|
18
|
+
| `qrcode` | `1.5.4` | QR code generation for OTP URIs |
|
|
19
|
+
| `@types/qrcode` | `1.5.5` | TypeScript definitions for qrcode |
|
|
20
|
+
|
|
21
|
+
## Usage
|
|
22
|
+
|
|
23
|
+
### Setup flow
|
|
24
|
+
|
|
25
|
+
```typescript
|
|
26
|
+
@Controller('auth/2fa')
|
|
27
|
+
export class TwoFactorController {
|
|
28
|
+
constructor(private readonly totpService: TotpService) {}
|
|
29
|
+
|
|
30
|
+
@Post('enable')
|
|
31
|
+
async enable(@CurrentUser() user: User) {
|
|
32
|
+
const secret = this.totpService.generateSecret();
|
|
33
|
+
// Store the secret (encrypted) in the user record
|
|
34
|
+
const qrCode = await this.totpService.generateQrCode(user.email, secret, 'MyApp');
|
|
35
|
+
const backupCodes = this.totpService.generateBackupCodes();
|
|
36
|
+
// Hash and store backup codes
|
|
37
|
+
return { qrCode, backupCodes };
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
@Post('verify')
|
|
41
|
+
async verify(@CurrentUser() user: User, @Body('token') token: string) {
|
|
42
|
+
const isValid = this.totpService.verify(token, user.totpSecret);
|
|
43
|
+
if (!isValid) throw new UnauthorizedException('Invalid 2FA token');
|
|
44
|
+
// Mark 2FA as verified for this session
|
|
45
|
+
return { verified: true };
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
### QR code setup
|
|
51
|
+
|
|
52
|
+
1. Call `generateSecret()` and store the secret (encrypted) with the user
|
|
53
|
+
2. Call `generateQrCode(email, secret, issuer)` to get a data URI
|
|
54
|
+
3. Display the QR code to the user for scanning with an authenticator app
|
|
55
|
+
4. Verify a token from the app with `verify(token, secret)` before activating 2FA
|
|
56
|
+
|
|
57
|
+
### Backup codes
|
|
58
|
+
|
|
59
|
+
- Generate with `generateBackupCodes()` during 2FA setup
|
|
60
|
+
- Display to the user once and instruct them to store securely
|
|
61
|
+
- Hash each code (e.g., with bcrypt) before persisting to the database
|
|
62
|
+
- Each code is single-use: mark as consumed after successful verification
|
|
63
|
+
- Provide a way to regenerate codes (which invalidates old ones)
|
|
64
|
+
|
|
65
|
+
### Security considerations
|
|
66
|
+
|
|
67
|
+
- Store TOTP secrets encrypted at rest, not in plain text
|
|
68
|
+
- Hash backup codes before persisting (same as passwords)
|
|
69
|
+
- Rate-limit verification attempts to prevent brute force
|
|
70
|
+
- Consider a time window tolerance (otplib defaults to 1 step = 30 seconds)
|
|
71
|
+
- Require re-authentication before enabling or disabling 2FA
|
|
72
|
+
|
|
73
|
+
## Generated Files
|
|
74
|
+
|
|
75
|
+
| File | Description |
|
|
76
|
+
| --------------------------------- | -------------------------------------------------------- |
|
|
77
|
+
| `src/shared/auth/totp.service.ts` | TOTP service for secret generation, QR codes, and verify |
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { Injectable } from '@nestjs/common';
|
|
2
|
+
import { randomBytes } from 'node:crypto';
|
|
3
|
+
import { authenticator } from 'otplib';
|
|
4
|
+
import * as QRCode from 'qrcode';
|
|
5
|
+
|
|
6
|
+
@Injectable()
|
|
7
|
+
export class TotpService {
|
|
8
|
+
generateSecret(): string {
|
|
9
|
+
return authenticator.generateSecret();
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
async generateQrCode(email: string, secret: string, issuer: string = 'App'): Promise<string> {
|
|
13
|
+
const otpauthUrl = authenticator.keyuri(email, issuer, secret);
|
|
14
|
+
return QRCode.toDataURL(otpauthUrl);
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
verify(token: string, secret: string): boolean {
|
|
18
|
+
return authenticator.verify({ token, secret });
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
generateBackupCodes(count: number = 10): string[] {
|
|
22
|
+
return Array.from({ length: count }, () =>
|
|
23
|
+
randomBytes(4).toString('hex').toUpperCase().slice(0, 6),
|
|
24
|
+
);
|
|
25
|
+
}
|
|
26
|
+
}
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
import { Test } from '@nestjs/testing';
|
|
2
|
+
import { TotpService } from '@/shared/auth/totp.service';
|
|
3
|
+
|
|
4
|
+
describe('TotpService', () => {
|
|
5
|
+
let service: TotpService;
|
|
6
|
+
|
|
7
|
+
beforeEach(async () => {
|
|
8
|
+
const module = await Test.createTestingModule({
|
|
9
|
+
providers: [TotpService],
|
|
10
|
+
}).compile();
|
|
11
|
+
|
|
12
|
+
service = module.get(TotpService);
|
|
13
|
+
});
|
|
14
|
+
|
|
15
|
+
it('should be defined', () => {
|
|
16
|
+
expect(service).toBeDefined();
|
|
17
|
+
});
|
|
18
|
+
|
|
19
|
+
describe('generateSecret', () => {
|
|
20
|
+
it('should return a non-empty base32-encoded string', () => {
|
|
21
|
+
const secret = service.generateSecret();
|
|
22
|
+
expect(secret).toBeDefined();
|
|
23
|
+
expect(secret.length).toBeGreaterThan(0);
|
|
24
|
+
expect(secret).toMatch(/^[A-Z2-7]+=*$/);
|
|
25
|
+
});
|
|
26
|
+
|
|
27
|
+
it('should generate unique secrets on each call', () => {
|
|
28
|
+
const secretA = service.generateSecret();
|
|
29
|
+
const secretB = service.generateSecret();
|
|
30
|
+
expect(secretA).not.toEqual(secretB);
|
|
31
|
+
});
|
|
32
|
+
});
|
|
33
|
+
|
|
34
|
+
describe('verify', () => {
|
|
35
|
+
it('should return false for an incorrect token', () => {
|
|
36
|
+
const secret = service.generateSecret();
|
|
37
|
+
const result = service.verify('000000', secret);
|
|
38
|
+
// While there is a tiny chance this is the current TOTP, it is
|
|
39
|
+
// statistically negligible and acceptable for a unit test.
|
|
40
|
+
expect(typeof result).toBe('boolean');
|
|
41
|
+
});
|
|
42
|
+
|
|
43
|
+
it('should return a boolean result', () => {
|
|
44
|
+
const secret = service.generateSecret();
|
|
45
|
+
const result = service.verify('123456', secret);
|
|
46
|
+
expect(result).toBe(true || false); // boolean guard
|
|
47
|
+
expect([true, false]).toContain(result);
|
|
48
|
+
});
|
|
49
|
+
});
|
|
50
|
+
|
|
51
|
+
describe('generateBackupCodes', () => {
|
|
52
|
+
it('should generate the default count of 10 backup codes', () => {
|
|
53
|
+
const codes = service.generateBackupCodes();
|
|
54
|
+
expect(codes).toHaveLength(10);
|
|
55
|
+
codes.forEach((code) => {
|
|
56
|
+
expect(code).toMatch(/^[A-Z0-9]{6}$/);
|
|
57
|
+
});
|
|
58
|
+
});
|
|
59
|
+
|
|
60
|
+
it('should generate the specified number of backup codes', () => {
|
|
61
|
+
const codes = service.generateBackupCodes(5);
|
|
62
|
+
expect(codes).toHaveLength(5);
|
|
63
|
+
});
|
|
64
|
+
});
|
|
65
|
+
});
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
# MikroORM + PostgreSQL
|
|
2
|
+
|
|
3
|
+
Data Mapper ORM with Unit of Work and Identity Map, ideal for Domain-Driven Design.
|
|
4
|
+
|
|
5
|
+
## Resources
|
|
6
|
+
|
|
7
|
+
- [NestJS MikroORM recipe](https://docs.nestjs.com/recipes/mikroorm)
|
|
8
|
+
- [MikroORM documentation](https://mikro-orm.io/docs/)
|
|
9
|
+
- [@mikro-orm/core on npm](https://www.npmjs.com/package/@mikro-orm/core)
|
|
10
|
+
|
|
11
|
+
## Package.json scripts
|
|
12
|
+
|
|
13
|
+
Add the following scripts to your `package.json`:
|
|
14
|
+
|
|
15
|
+
```json
|
|
16
|
+
{
|
|
17
|
+
"mikro-orm": "mikro-orm",
|
|
18
|
+
"migration:create": "mikro-orm migration:create",
|
|
19
|
+
"migration:up": "mikro-orm migration:up",
|
|
20
|
+
"migration:down": "mikro-orm migration:down"
|
|
21
|
+
}
|
|
22
|
+
```
|
|
File without changes
|
|
File without changes
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { Options } from '@mikro-orm/core';
|
|
2
|
+
import { PostgreSqlDriver } from '@mikro-orm/postgresql';
|
|
3
|
+
import { Migrator } from '@mikro-orm/migrations';
|
|
4
|
+
|
|
5
|
+
const config: Options<PostgreSqlDriver> = {
|
|
6
|
+
driver: PostgreSqlDriver,
|
|
7
|
+
host: process.env.DB_HOST ?? 'localhost',
|
|
8
|
+
port: Number(process.env.DB_PORT ?? 5432),
|
|
9
|
+
dbName: process.env.DB_NAME ?? 'app',
|
|
10
|
+
user: process.env.DB_USERNAME ?? 'postgres',
|
|
11
|
+
password: process.env.DB_PASSWORD ?? (() => { throw new Error('DB_PASSWORD environment variable is required'); })(),
|
|
12
|
+
entities: ['./dist/infrastructure/database/entities/*.js'],
|
|
13
|
+
entitiesTs: ['./src/infrastructure/database/entities/*.ts'],
|
|
14
|
+
extensions: [Migrator],
|
|
15
|
+
migrations: {
|
|
16
|
+
path: './src/infrastructure/database/migrations',
|
|
17
|
+
},
|
|
18
|
+
};
|
|
19
|
+
|
|
20
|
+
export default config;
|
package/templates/recipes/mikro-orm/tests/unit/infrastructure/database/mikro-orm.config.spec.ts
ADDED
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
describe('MikroORM config', () => {
|
|
2
|
+
const originalEnv = process.env;
|
|
3
|
+
|
|
4
|
+
beforeEach(() => {
|
|
5
|
+
jest.resetModules();
|
|
6
|
+
process.env = { ...originalEnv };
|
|
7
|
+
});
|
|
8
|
+
|
|
9
|
+
afterAll(() => {
|
|
10
|
+
process.env = originalEnv;
|
|
11
|
+
});
|
|
12
|
+
|
|
13
|
+
it('should use default values when environment variables are not set', () => {
|
|
14
|
+
delete process.env.DB_HOST;
|
|
15
|
+
delete process.env.DB_PORT;
|
|
16
|
+
delete process.env.DB_NAME;
|
|
17
|
+
delete process.env.DB_USERNAME;
|
|
18
|
+
delete process.env.DB_PASSWORD;
|
|
19
|
+
|
|
20
|
+
// eslint-disable-next-line @typescript-eslint/no-require-imports
|
|
21
|
+
const config = require('../../../../src/infrastructure/database/mikro-orm.config').default;
|
|
22
|
+
|
|
23
|
+
expect(config.host).toBe('localhost');
|
|
24
|
+
expect(config.port).toBe(5432);
|
|
25
|
+
expect(config.dbName).toBe('app');
|
|
26
|
+
expect(config.user).toBe('postgres');
|
|
27
|
+
expect(config.password).toBe('postgres');
|
|
28
|
+
});
|
|
29
|
+
|
|
30
|
+
it('should pick up custom environment variables', () => {
|
|
31
|
+
process.env.DB_HOST = '10.0.0.1';
|
|
32
|
+
process.env.DB_PORT = '5433';
|
|
33
|
+
process.env.DB_NAME = 'mydb';
|
|
34
|
+
process.env.DB_USERNAME = 'admin';
|
|
35
|
+
process.env.DB_PASSWORD = 's3cret';
|
|
36
|
+
|
|
37
|
+
// eslint-disable-next-line @typescript-eslint/no-require-imports
|
|
38
|
+
const config = require('../../../../src/infrastructure/database/mikro-orm.config').default;
|
|
39
|
+
|
|
40
|
+
expect(config.host).toBe('10.0.0.1');
|
|
41
|
+
expect(config.port).toBe(5433);
|
|
42
|
+
expect(config.dbName).toBe('mydb');
|
|
43
|
+
expect(config.user).toBe('admin');
|
|
44
|
+
expect(config.password).toBe('s3cret');
|
|
45
|
+
});
|
|
46
|
+
|
|
47
|
+
it('should include the Migrator extension', () => {
|
|
48
|
+
// eslint-disable-next-line @typescript-eslint/no-require-imports
|
|
49
|
+
const config = require('../../../../src/infrastructure/database/mikro-orm.config').default;
|
|
50
|
+
expect(config.extensions).toBeDefined();
|
|
51
|
+
expect(config.extensions.length).toBeGreaterThanOrEqual(1);
|
|
52
|
+
});
|
|
53
|
+
});
|